get('logged_in')) { return null; // 비로그인 요청은 통과 } $mbIdx = (int) ($session->get('mb_idx') ?? 0); if ($mbIdx <= 0) { return null; } $member = model(MemberModel::class)->find($mbIdx); if ($member === null) { return null; } $dbToken = (string) ($member->mb_session_token ?? ''); $myToken = (string) ($session->get('session_token') ?? ''); // DB에 토큰이 있고 내 세션 토큰과 다르면 → 다른 곳에서 더 늦게 로그인한 것 if ($dbToken !== '' && $dbToken !== $myToken) { $session->destroy(); // AJAX/JSON 요청은 401, 일반 요청은 로그인으로 if (strtolower((string) $request->getHeaderLine('X-Requested-With')) === 'xmlhttprequest' || str_contains(strtolower((string) $request->getHeaderLine('Accept')), 'application/json')) { return service('response')->setStatusCode(401)->setJSON([ 'ok' => false, 'message' => '다른 곳에서 로그인되어 로그아웃되었습니다.', ]); } return redirect()->to(site_url('login'))->with('error', '다른 곳에서 로그인되어 자동 로그아웃되었습니다.'); } return null; } public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) { // no-op } }