diff --git a/app/Controllers/Auth.php b/app/Controllers/Auth.php index d34aa3e..ff94fb9 100644 --- a/app/Controllers/Auth.php +++ b/app/Controllers/Auth.php @@ -565,16 +565,39 @@ class Auth extends BaseController 'mb_locked_until' => null, ]); + // 로그인 알림 — 직전 성공 로그인과 IP 비교(새 IP면 경고). 현재 로그인 기록 INSERT 이전에 조회. + $loginNotice = ''; + try { + $curIp = (string) $this->request->getIPAddress(); + $prev = model(MemberLogModel::class) + ->where('mb_idx', (int) $member->mb_idx) + ->where('mll_success', 1) + ->orderBy('mll_idx', 'DESC') + ->first(); + if ($prev) { + $prevIp = (string) ($prev->mll_ip ?? ''); + $prevAt = (string) ($prev->mll_regdate ?? ''); + if ($prevIp !== '' && $prevIp !== $curIp) { + $loginNotice = ' ⚠ 새로운 환경(IP ' . $curIp . ')에서 로그인되었습니다. 본인이 아니면 비밀번호를 변경하세요. (이전 로그인: ' . $prevAt . ' · ' . $prevIp . ')'; + } elseif ($prevAt !== '') { + $loginNotice = ' (이전 로그인: ' . $prevAt . ')'; + } + } + } catch (\Throwable $e) { + // 알림 계산 실패는 로그인에 영향 주지 않음 + } + $this->insertMemberLog($logData, true, '로그인 성공', (int) $member->mb_idx); + $successMsg = '로그인되었습니다.' . $loginNotice; if ((int) $member->mb_level === \Config\Roles::LEVEL_LOCAL_ADMIN) { - return redirect()->to(site_url('admin'))->with('success', '로그인되었습니다.'); + return redirect()->to(site_url('admin'))->with('success', $successMsg); } if (\Config\Roles::isSuperAdminEquivalent((int) $member->mb_level)) { - return redirect()->to(site_url('admin/select-local-government'))->with('success', '로그인되었습니다.'); + return redirect()->to(site_url('admin/select-local-government'))->with('success', $successMsg); } - return redirect()->to(site_url('/'))->with('success', '로그인되었습니다.'); + return redirect()->to(site_url('/'))->with('success', $successMsg); } private function buildLogData(string $mbId, ?int $mbIdx): array