변경 파일 목록
총 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 ?>ncds/css/duplicate-login-ncds.css"/> | |
| <form id="frmDuplicateLogin" action="login_ps.php" method="post"> | |
| <input type="hidden" name="mode" value="concurrentLoginConfirm"/> | |
| <input type="hidden" name="returnUrl" value=""/> | |
| <input type="hidden" name="keepExisting" id="keepExistingInput" value="n"/> | |
| </form> | |
| <script> | |
| (() => { | |
| const init = () => { | |
| if (typeof window.ncua === 'undefined' || typeof window.ncua.Modal === 'undefined') { | |
| setTimeout(init, 50); | |
| return; | |
| } | |
| const makeBtn = (label, hierarchy, onClick) => { | |
| if (window.createButton) { return window.createButton(label, hierarchy, onClick, 'sm'); } | |
| const tpl = document.createElement('template'); | |
| tpl.innerHTML = `<button type="button" class="ncua-btn ncua-btn--sm ncua-btn--${hierarchy}"><span class="ncua-btn__label">${label}</span></button>`; | |
| const btn = tpl.content.firstElementChild; | |
| btn.addEventListener('click', onClick); | |
| return btn; | |
| }; | |
| const cancel = () => { | |
| location.href = '/base/login_ps.php?mode=logout'; | |
| }; | |
| const modal = new window.ncua.Modal({ | |
| size: 'lg', | |
| className: 'duplicate-login-ncds-modal', | |
| closeOnBackdropClick: false, | |
| onClose: cancel, | |
| }); | |
| const header = new window.ncua.Modal.Header({ | |
| title: '고객님의 계정이 이미 사용중입니다.', | |
| }); | |
| header.setCloseHandler(cancel); | |
| const contentHtml = ` | |
| <div class="duplicate-login-ncds-content"> | |
| <p class="duplicate-login-ncds-desc"> | |
| • 고객님의 계정이 다른 IP에서 로그인되었습니다. 아래 버튼을 선택하여 로그인을 진행해주세요.<br> | |
| • 안전하게 이용하려면 이전 로그인을 종료하고 새로 로그인해주세요. | |
| </p> | |
| <div class="ncua-table ncua-table--vertical"> | |
| <table> | |
| <colgroup><col width="50%"><col width="50%"></colgroup> | |
| <tbody> | |
| <tr> | |
| <th><div>현재 로그인한 IP</div></th> | |
| <td><div><?= gd_htmlspecialchars($currentLoginIp) ?></div></td> | |
| </tr> | |
| <tr> | |
| <th><div>이전 로그인한 IP</div></th> | |
| <td><div><?= gd_htmlspecialchars($lastLoginIp) ?></div></td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </div> | |
| <div class="duplicate-login-ncds-radio-group"> | |
| <label class="ncua-radio-field ncua-radio-field--xs has-text"> | |
| <span class="ncua-radio-input ncua-radio-input--xs ncua-radio-field__input"> | |
| <input type="radio" name="keepExistingModal" value="y" checked /> | |
| </span> | |
| <span><span class="ncua-radio-field__text">이전 로그인을 그대로 유지한 상태에서 로그인 (동시 로그인 허용)</span></span> | |
| </label> | |
| <label class="ncua-radio-field ncua-radio-field--xs has-text"> | |
| <span class="ncua-radio-input ncua-radio-input--xs ncua-radio-field__input"> | |
| <input type="radio" name="keepExistingModal" value="n" /> | |
| </span> | |
| <span><span class="ncua-radio-field__text">이전 로그인은 종료하고, 새로 로그인</span></span> | |
| </label> | |
| </div> | |
| </div> | |
| `; | |
| const content = new window.ncua.Modal.Content(contentHtml); | |
| const actions = new window.ncua.Modal.Actions('', { layout: 'horizontal', align: 'right' }); | |
| const confirmBtn = makeBtn('확인', 'primary', () => { | |
| const checked = modal.getModalElement().querySelector('input[name="keepExistingModal"]: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잠시 후 다시 시도해 주세요.'); | |
| }); | |
| }); | |
| const cancelBtn = makeBtn('취소', 'secondary-gray', cancel); | |
| actions.setContent([cancelBtn, confirmBtn]); | |
| const modalEl = modal.getModalElement(); | |
| header.appendTo(modalEl); | |
| content.appendTo(modalEl); | |
| actions.appendTo(modalEl); | |
| modal.open(); | |
| }; | |
| init(); | |
| })(); | |
| </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\Admin\Menu\AdminMenuFlagService; | |
| 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\Admin\Menu\AdminMenuFlagService; | |
| use Origin\Service\Member\ManagerLogoutService; | |
| use Origin\Service\Storage\ManagerDuplicateLoginService; | |
| use Password; | |
| use Request; | |
| use Session; | |
| */ | |
| private $_storage; | |
| private ManagerDuplicateLoginService $managerLoginStorage; | |
| /** @var bool 중복 로그인으로 인한 (강제) 로그아웃 여부 */ | |
| private bool $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(); | |
| } | |
| public function setDuplicateLoginList(int $sno): void | |
| { | |
| $this->managerLoginStorage->addCurrentLoginToList($sno); | |
| } | |
| /** | |
| * setManagerOldMenuAccessChange | |
| * 운영자 세부 접속 권한 마이그레이션 | |
| } | |
| } | |
| /** | |
| * 중복 로그인으로 인한 (강제) 로그아웃 여부 주입. | |
| * managerLogout() 을 무인자로 유지하기 위해 파라미터 대신 setter 로 받는다. | |
| * | |
| * @param bool $shouldDuplicateLogout true 면 es_adminLog 에 세션 종료 action 으로 기록 | |
| */ | |
| public function setShouldDuplicateLogout(bool $shouldDuplicateLogout): void | |
| { | |
| $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); | |
| } | |
| public function isCurrentLoginRegistered(): bool | |
| { | |
| return $this->managerLoginStorage->isCurrentLoginRegistered(); | |
| } | |
| public function isDuplicateLogin(): bool | |
| { | |
| return $this->managerLoginStorage->isDuplicateLatestLogin(); | |
| } | |
| public function getLastLoginIp(): ?string | |
| { | |
| return $this->managerLoginStorage->getPreviousLoginIp(); | |
| } | |
| public function allLogoutWithoutMe(): void | |
| { | |
| $this->managerLoginStorage->deleteLoginAllWithoutMe(); | |
| } | |
| } | |
변경 전IndexController.php
| use Component\Member\Manager; | |
| use Core\Base\View\Alert; | |
| use Framework\Enum\ExternalUrl; | |
| 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\Enum\ExternalUrl; | |
| 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; | |
| } | |
| } | |
| } | |