변경 파일 목록
총 5개
Admin (1)
duplicate_login.phpbase/Controller (1)
IndexController.phpAdmin/Base/변경 파일 코드
추가삭제
변경 전duplicate_login.php
변경 후duplicate_login.php
| <link rel="stylesheet" href="<?= PATH_ADMIN_GD_SHARE ?>css/duplicate-login.css"/> | |
| <form id="frmDuplicateLogin" action="login_ps.php" method="post"> | |
| <input type="hidden" name="mode" value="concurrentLoginConfirm"/> | |
| <input type="hidden" name="returnUrl" value=""/> | |
| <div class="duplicate-login-backdrop"> | |
| <div class="duplicate-login-dialog"> | |
| <a href="/base/login_ps.php?mode=logout" class="close duplicate-login-close" aria-label="닫기">×</a> | |
| <h2 class="duplicate-login-title">고객님의 계정이 이미 사용중입니다.</h2> | |
| <div class="duplicate-login-content"> | |
| <p class="duplicate-login-desc"> | |
| • 고객님의 계정이 다른 IP에서 로그인되었습니다. 아래 버튼을 선택하여 로그인을 진행해주세요.<br> | |
| • 안전하게 이용하려면 이전 로그인을 종료하고 새로 로그인해주세요. | |
| </p> | |
| <table class="duplicate-login-ip-table"> | |
| <colgroup> | |
| <col width="50%"> | |
| <col width="50%"> | |
| </colgroup> | |
| <tbody> | |
| <tr> | |
| <th>현재 로그인한 IP</th> | |
| <td><?= gd_htmlspecialchars($currentLoginIp) ?></td> | |
| </tr> | |
| <tr> | |
| <th>이전 로그인한 IP</th> | |
| <td><?= gd_htmlspecialchars($lastLoginIp) ?></td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <div class="duplicate-login-options"> | |
| <label class="duplicate-login-option"> | |
| <input type="radio" name="keepExisting" value="y" checked /> | |
| 이전 로그인을 그대로 유지한 상태에서 로그인 (동시 로그인 허용) | |
| </label> | |
| <label class="duplicate-login-option"> | |
| <input type="radio" name="keepExisting" value="n" /> | |
| 이전 로그인은 종료하고, 새로 로그인 | |
| </label> | |
| </div> | |
| </div> | |
| <div class="duplicate-login-actions"> | |
| <a href="/base/login_ps.php?mode=logout" class="btn btn-white">취소</a> | |
| <input type="submit" value="확인" class="btn btn-black"/> | |
| </div> | |
| </div> | |
| </div> | |
| </form> | |
| <script> | |
| (() => { | |
| const form = document.getElementById('frmDuplicateLogin'); | |
| if (!form) { return; } | |
| form.addEventListener('submit', (e) => { | |
| e.preventDefault(); | |
| const checked = form.querySelector('input[name="keepExisting"]:checked'); | |
| const keepExisting = checked?.value ?? 'n'; | |
| const standalone = keepExisting !== 'y'; | |
| fetch('/share/duplicate_login_ps.php', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Accept': 'application/json', | |
| 'X-Requested-With': 'XMLHttpRequest', | |
| }, | |
| body: JSON.stringify({ standalone: standalone }), | |
| }).then((response) => { | |
| if (!response.ok) { | |
| throw new Error('request failed'); | |
| } | |
| location.reload(); | |
| }).catch(() => { | |
| alert('요청하신 작업을 완료하지 못했습니다.\n잠시 후 다시 시도해 주세요.'); | |
| }); | |
| }); | |
| })(); | |
| </script> | |
변경 전AdminLogDAO.php
| const LOGIN = 'login'; | |
| const LOGOUT = 'logout'; | |
| const ALLOWED_MODES = ['authEmail', 'authSms', 'register', 'modify', 'delete', 'setManagePermission', 'getManagerListLayout']; | |
| $page = '주문 내역 삭제'; | |
| } | |
| $logType = $pageData['type'] ?? AdminLogDAO::LOG_TYPE_P2Y; | |
| // 개인정보접속기록 다운로드로그 5년보관 | |
| if ($page == 'adminLogExcel') { | |
변경 후AdminLogDAO.php
| const LOGIN = 'login'; | |
| const LOGOUT = 'logout'; | |
| const LOGOUT_SESSION_END = 'logoutSessionEnd'; | |
| const ALLOWED_MODES = ['authEmail', 'authSms', 'register', 'modify', 'delete', 'setManagePermission', 'getManagerListLayout']; | |
| $page = '주문 내역 삭제'; | |
| } | |
| if ($mode === self::LOGOUT_SESSION_END) { | |
| $page = 'adminInfo'; | |
| $action = '로그아웃(세션 종료)'; | |
| } | |
| $logType = $pageData['type'] ?? AdminLogDAO::LOG_TYPE_P2Y; | |
| // 개인정보접속기록 다운로드로그 5년보관 | |
| if ($page == 'adminLogExcel') { | |
변경 전ManagerCs.php
| use Framework\Debug\Exception\DatabaseException; | |
| use Framework\Security\Digester; | |
| use Framework\Security\Otp; | |
| use Framework\Utility\ComponentUtils; | |
| use Framework\Utility\DateTimeUtils; | |
| use Framework\Utility\StringUtils; | |
| use Framework\Utility\GodoUtils; | |
| /** | |
| * Class ManagerCs | |
| * @package Bundle\Component\Member | |
| $request = \App::getInstance('request'); | |
| $session = \App::getInstance('session'); | |
| $logger = \App::getInstance('logger'); | |
| $this->db->query_reset(); | |
| $data['lastLoginIp'] = $request->getRemoteAddress(); | |
| $data['sessionLimitTime'] = $sessionLimitTime; | |
| $session->del(self::SESSION_TEMP_MANAGER); | |
| $session->set(self::SESSION_MANAGER_LOGIN, $data); | |
| } | |
| /** | |
변경 후ManagerCs.php
| use Framework\Debug\Exception\DatabaseException; | |
| use Framework\Security\Digester; | |
| use Framework\Security\Otp; | |
| use Framework\SimpleCache\SimpleCache; | |
| use Framework\Utility\ComponentUtils; | |
| use Framework\Utility\DateTimeUtils; | |
| use Framework\Utility\StringUtils; | |
| use Framework\Utility\GodoUtils; | |
| use Origin\Service\Storage\ManagerDuplicateLoginService; | |
| /** | |
| * Class ManagerCs | |
| * @package Bundle\Component\Member | |
| $request = \App::getInstance('request'); | |
| $session = \App::getInstance('session'); | |
| $logger = \App::getInstance('logger'); | |
| $duplicateLoginService = new ManagerDuplicateLoginService( | |
| \App::getInstance('application'), | |
| \App::getInstance('session'), | |
| SimpleCache::init(SimpleCache::REDIS) | |
| ); | |
| $this->db->query_reset(); | |
| $data['lastLoginIp'] = $request->getRemoteAddress(); | |
| $data['sessionLimitTime'] = $sessionLimitTime; | |
| $session->del(self::SESSION_TEMP_MANAGER); | |
| $session->set(self::SESSION_MANAGER_LOGIN, $data); | |
| $duplicateLoginService->addCurrentLoginToList($data['sno']); | |
| } | |
| /** | |
변경 전Manager.php
| namespace Bundle\Component\Member; | |
| use Component\Admin\AdminMenu; | |
| use Component\Database\DBTableField; | |
| use Component\Member\Exception\LoginException; | |
| use Framework\Debug\Exception\AlertRedirectException; | |
| use Framework\Security\Digester; | |
| use Framework\Security\Otp; | |
| use Framework\Utility\ComponentUtils; | |
| use Framework\Utility\DateTimeUtils; | |
| use Framework\Utility\GodoUtils; | |
| use Framework\Utility\StringUtils; | |
| use Origin\Service\Member\ManagerLogoutService; | |
| use Password; | |
| use Request; | |
| use Session; | |
| */ | |
| private $_storage; | |
| /** | |
| * 생성자 | |
| */ | |
| $this->smsAutoReceiveKind[$newKey] = $val; | |
| } | |
| unset($tmp, $newKey); | |
| } | |
| /** | |
| $this->setManagerOldMenuAccessChange(); // 운영자 접속 권한 - 세부 권한으로 마이그레이션 | |
| $this->setManagerFunctionAuthChange(); // 운영자 기능 권한 - 기능 권한으로 마이그레이션 | |
| $this->setManagerScmFunctionAuthChange(); // 공급사 기능 권한 - 기능 권한으로 마이그레이션 | |
| // 관리자 로그인 성공 로그 | |
| $request->request()->set('adminLoginFl', true); | |
| $adminMenuFlagService->updateAdminMenuFlagsInSession(); | |
| } | |
| /** | |
| * setManagerOldMenuAccessChange | |
| * 운영자 세부 접속 권한 마이그레이션 | |
| } | |
| } | |
| /** | |
| * 관리자 로그아웃 | |
| */ | |
| public function managerLogout() | |
| { | |
| $cookie = \App::getInstance('cookie'); | |
| // 관리자 로그아웃 로그 작성 | |
| $adminLog = \App::load('Component\\Admin\\AdminLogDAO'); | |
| $adminLog->setAdminLog($adminLog::LOGOUT); | |
| // 세션을 없애기전에 세션 쿠키를 지웁니다. | |
| if ($cookie->has($session->getName())) { | |
| // 관리자 통합회원 로그아웃 | |
| /** @var ManagerLogoutService $managerLogoutService */ | |
| $managerLogoutService = \App::getInstance(ManagerLogoutService::class); | |
| $managerLogoutService->logout(); | |
| // 관리자만 로그아웃하는 경우 세션 클리어 | |
| if (MemberUtil::isLogin()) { | |
| } | |
| if ($result > 0 && $type != 'reset') { | |
| Manager::managerLogout(); | |
| } | |
| } | |
| unset($arrBind); | |
| return gd_htmlspecialchars_stripslashes($data); | |
| } | |
| } | |
변경 후Manager.php
| namespace Bundle\Component\Member; | |
| use Component\Admin\AdminLogDAO; | |
| use Component\Admin\AdminMenu; | |
| use Component\Database\DBTableField; | |
| use Component\Member\Exception\LoginException; | |
| use Framework\Debug\Exception\AlertRedirectException; | |
| use Framework\Security\Digester; | |
| use Framework\Security\Otp; | |
| use Framework\SimpleCache\SimpleCache; | |
| use Framework\Utility\ComponentUtils; | |
| use Framework\Utility\DateTimeUtils; | |
| use Framework\Utility\GodoUtils; | |
| use Framework\Utility\StringUtils; | |
| use Origin\Service\Member\ManagerLogoutService; | |
| use Origin\Service\Storage\ManagerDuplicateLoginService; | |
| use Password; | |
| use Request; | |
| use Session; | |
| */ | |
| private $_storage; | |
| /** @var ManagerDuplicateLoginService */ | |
| private $managerLoginStorage; | |
| /** @var bool 중복 로그인으로 인한 (강제) 로그아웃 여부 */ | |
| private $shouldDuplicateLogout = false; | |
| /** | |
| * 생성자 | |
| */ | |
| $this->smsAutoReceiveKind[$newKey] = $val; | |
| } | |
| unset($tmp, $newKey); | |
| $this->managerLoginStorage = new ManagerDuplicateLoginService( | |
| \App::getInstance('application'), | |
| \App::getInstance('session'), | |
| SimpleCache::init(SimpleCache::REDIS) | |
| ); | |
| } | |
| /** | |
| $this->setManagerOldMenuAccessChange(); // 운영자 접속 권한 - 세부 권한으로 마이그레이션 | |
| $this->setManagerFunctionAuthChange(); // 운영자 기능 권한 - 기능 권한으로 마이그레이션 | |
| $this->setManagerScmFunctionAuthChange(); // 공급사 기능 권한 - 기능 권한으로 마이그레이션 | |
| $this->setDuplicateLoginList($data['sno']); // 중복 로그인 감지용 로그인 세션 목록에 현재 세션 등록 | |
| // 관리자 로그인 성공 로그 | |
| $request->request()->set('adminLoginFl', true); | |
| $adminMenuFlagService->updateAdminMenuFlagsInSession(); | |
| } | |
| /** | |
| * 동시 로그인 정보를 Redis 에 등록한다. | |
| * | |
| * @param int $sno 관리자 sno | |
| */ | |
| public function setDuplicateLoginList(int $sno) | |
| { | |
| $this->managerLoginStorage->addCurrentLoginToList($sno); | |
| } | |
| /** | |
| * setManagerOldMenuAccessChange | |
| * 운영자 세부 접속 권한 마이그레이션 | |
| } | |
| } | |
| /** | |
| * 중복 로그인으로 인한 (강제) 로그아웃 여부 주입. | |
| * managerLogout() 을 무인자로 유지하기 위해 파라미터 대신 setter 로 받는다. | |
| * | |
| * @param bool $shouldDuplicateLogout true 면 es_adminLog 에 세션 종료 action 으로 기록 | |
| * @return void | |
| */ | |
| public function setShouldDuplicateLogout(bool $shouldDuplicateLogout) | |
| { | |
| $this->shouldDuplicateLogout = $shouldDuplicateLogout; | |
| } | |
| /** | |
| * 관리자 로그아웃 | |
| * 중복 로그인 여부는 setShouldDuplicateLogout() 로 주입한다. | |
| */ | |
| public function managerLogout() | |
| { | |
| $cookie = \App::getInstance('cookie'); | |
| // 관리자 로그아웃 로그 작성 | |
| /** @var AdminLogDAO $adminLog */ | |
| $adminLog = \App::load('Component\\Admin\\AdminLogDAO'); | |
| $adminLog->setAdminLog($this->shouldDuplicateLogout ? $adminLog::LOGOUT_SESSION_END : $adminLog::LOGOUT); | |
| // 세션을 없애기전에 세션 쿠키를 지웁니다. | |
| if ($cookie->has($session->getName())) { | |
| // 관리자 통합회원 로그아웃 | |
| /** @var ManagerLogoutService $managerLogoutService */ | |
| $managerLogoutService = \App::getInstance(ManagerLogoutService::class); | |
| $managerLogoutService->logout($this->shouldDuplicateLogout); | |
| $this->managerLoginStorage->deleteCurrentLoginFromList(); | |
| // 관리자만 로그아웃하는 경우 세션 클리어 | |
| if (MemberUtil::isLogin()) { | |
| } | |
| if ($result > 0 && $type != 'reset') { | |
| $this->managerLogout(); | |
| } | |
| } | |
| unset($arrBind); | |
| return gd_htmlspecialchars_stripslashes($data); | |
| } | |
| /** | |
| * @return bool | |
| */ | |
| public function isCurrentLoginRegistered(): bool | |
| { | |
| return $this->managerLoginStorage->isCurrentLoginRegistered(); | |
| } | |
| /** | |
| * @return bool | |
| */ | |
| public function isDuplicateLogin(): bool | |
| { | |
| return $this->managerLoginStorage->isDuplicateLatestLogin(); | |
| } | |
| /** | |
| * @return string|null | |
| */ | |
| public function getLastLoginIp() | |
| { | |
| return $this->managerLoginStorage->getPreviousLoginIp(); | |
| } | |
| public function allLogoutWithoutMe() | |
| { | |
| $this->managerLoginStorage->deleteLoginAllWithoutMe(); | |
| } | |
| } | |
변경 전IndexController.php
| use Component\Member\Manager; | |
| use Core\Base\View\Alert; | |
| use Framework\Utility\StringUtils; | |
| use Origin\Service\License\LicenseRenewService; | |
| $mainSettingPolicy = \App::load('Component\\Policy\\MainSettingPolicy'); | |
| $sessionByManager = $session->get(Manager::SESSION_MANAGER_LOGIN); | |
| // 메인 통계의 권한 체크 | |
| $adminMenu = \App::load('Component\\Admin\\AdminMenu'); | |
| if ($this->getData('managerPermissionMethodExist') === true && $this->getData('adminMenuPermissionMethodExist') === true) { | |
| $this->getView()->setPageName('base/index.php'); | |
| } | |
| } | |
변경 후IndexController.php
| use Component\Member\Manager; | |
| use Core\Base\View\Alert; | |
| use Framework\Http\Session\SessionManager; | |
| use Framework\Utility\StringUtils; | |
| use Origin\Service\License\LicenseRenewService; | |
| $mainSettingPolicy = \App::load('Component\\Policy\\MainSettingPolicy'); | |
| $sessionByManager = $session->get(Manager::SESSION_MANAGER_LOGIN); | |
| $this->checkDuplicateLogin($session); | |
| // 메인 통계의 권한 체크 | |
| $adminMenu = \App::load('Component\\Admin\\AdminMenu'); | |
| if ($this->getData('managerPermissionMethodExist') === true && $this->getData('adminMenuPermissionMethodExist') === true) { | |
| $this->getView()->setPageName('base/index.php'); | |
| } | |
| public function checkDuplicateLogin(SessionManager $session) | |
| { | |
| $manager = \App::getInstance(\Manager::class); | |
| $request = \App::getInstance('request'); | |
| if ( | |
| $manager->isDuplicateLogin() && | |
| !$session->get('manager.allowDuplicateLogin') | |
| ) { | |
| $this->getView()->setDefine('layout', 'layout_blank_noiframe.php'); | |
| $this->getView()->setPageName('base/duplicate_login.php'); | |
| $this->getView()->setData('lastLoginIp',$manager->getLastLoginIp()); | |
| $this->getView()->setData('currentLoginIp', $request->getRemoteAddress()); | |
| echo $this->getView()->render(); | |
| exit; | |
| } | |
| } | |
| } | |