Files
jongryangje/docs/기본 개발계획/08-auth-login-flow-and-ci4-apply.md
2026-04-08 00:23:55 +09:00

9.4 KiB

Auth 로그인/로그아웃 플로우 정리 및 종량제(CI4) 적용 방안

slow-auth-application의 로그인/로그아웃이 어떻게 동작하는지 정리하고, 종량제 프로젝트(CI4)에 어떻게 적용할지 매핑한 문서입니다.


1. Auth 로그인 플로우 (현재 구조)

1.1 진입점

  • URL: GET /auth/login
  • 컨트롤러: Auth::login()
  • 전제:
    • 이미 logged_in 세션이 있으면 → /access 로 리다이렉트 (재로그인 불필요)
    • ?is_logout=1 이면 → /auth/logout 으로 보냄

1.2 폼 제출 (POST /auth/login)

  1. 입력 검증

    • mb_id(아이디): required
    • mb_passwd: required, min 4, max 20
    • 실패 시 → 로그인 뷰 다시 + form_validation->error_array() 로 에러 표시
  2. 회원 조회

    • access_get_member_info($mb_id, $auth_data) 호출
    • auth는 3종 계정 지원:
      • @ 없음 → member (일반 회원): member_m->login() 으로 member 테이블 조회
      • @ 있음 → group 또는 entity: member_group_m, member_entity_m 로 그룹/엔티티 로그인
    • 조회 실패 → access_log($msg, false, $mb_id) 로 실패 로그, 로그인 화면으로 alert 후 복귀
  3. 추가 검사 (member일 때만 해당)

    • 기간 설정 그룹: gp_period_yn, gp_startdate, gp_enddate 로 이용 기간 체크 → 밖이면 "unauthorized" 로그 + 실패
    • member_type == "group" 이면 임시 차단 메시지 + 실패
    • 비밀번호: password_verify($auth_data['mb_passwd'], $result->mb_passwd) 로 검증
    • 상태: mb_state != 1 이면 "탈퇴/정지" 메시지 + 실패, access_log 기록
  4. 로그인 성공

    • access_login_success($result) 호출:
      • access_set_token(): JWT 생성, access_token 테이블에 저장, 세션에 토큰 저장
      • access_log("You are logged in.", true, ...)member_log 테이블에 로그인 성공 로그 (1시간 내 중복 로그인은 한 건만 저장)
      • 세션에 저장: userinfo, depart(mb_group), access_token, lang, logged_in, last_activity
      • access_update_latest_data(): member/group/entity 별로 mb_latestdate 등 최근 로그인 시간 업데이트
    • 응답:
      • AJAX(is_ajax=true)면: JSON { result:1, redirect, token } 반환, 클라이언트가 localStorage에 토큰 저장 후 redirect 로 이동
      • 일반 폼이면: redirect('/access')
  5. 실패 시

    • "Please check your email and password." 등 메시지 + access_log(..., false) → 로그인 화면으로

1.3 로그인 후 첫 화면 (Access)

  • 기본 라우트: $route['default_controller'] = 'access'Access::index()
  • 동작:
    • 세션에 userinfo 없으면 → /auth/logout 으로 보냄
    • access_token 과 DB의 access_token 테이블 비교해서 유효한 토큰인지 확인 (super admin은 별도 처리)
    • 유효하면 Access::main() → 접근 가능한 앱 목록(access_list)을 보여주는 앱 선택 화면 (_access_view("/access_v"))
    • 앱이 1개면 해당 앱 URL로 바로 이동

1.4 로그아웃 (GET/POST /auth/logout)

  1. 세션에서 access_token 취득
  2. 토큰이 있으면:
    • member_log_m->update_logout_item_by_token($token) → 해당 로그인 로그에 로그아웃 시각 저장
    • access_token_m->item_delete_by_token($token) → DB에서 토큰 삭제
  3. ?is_logout=1 이면 클라이언트에 localStorage.clear() 스크립트 출력 (자동 로그인 토큰 제거)
  4. $this->session->sess_destroy() 로 세션 파기
  5. replace('/auth/login') → 로그인 페이지로 이동

1.5 보호 구간 (로그인 필수)

  • SL_Controller 상속 컨트롤러에서 _setting_view(), _access_view(), _modal_view() 등은 내부에서 _require_login() 호출
  • _require_login(): logged_in 세션이 없으면 "로그인화면으로 이동합니다." alert 후 /auth/logout 으로 보냄 (결국 로그인 페이지)

1.6 로그 저장 구조 (member_log)

  • 저장 시점: 로그인 시도(성공/실패), 로그인 성공 시 "You are logged in." 한 번, 로그아웃 시 mll_logout_date 업데이트
  • 필드 예: mll_ip, mll_useragent, mb_id, mb_idx, gp_idx, mll_success, mll_msg, mll_url, mll_country, at_token, mll_regdate, mll_logout_date

2. 종량제(CI4)에 적용할 때 매핑

2.1 줄이기 / 빼기

Auth 기능 종량제 적용
3종 계정 (member / group / entity) 1종만: 일반 사용자(member)만. group/entity 로그인 제거
JWT + access_token 테이블 (자동 로그인·다중 세션) Phase 1에서는 제거: 세션만 사용. 필요 시 Phase 2 이후에 "Remember me" 단순 구현
Access 앱 선택 화면 대체: 로그인 성공 시 /dashboard(또는 /admin)로 바로 이동. 앱 목록 불필요
access_get_country(), GeoIP 제거 또는 나중에: 로그에는 IP만 저장
1시간 내 중복 로그인 로그 억제 선택: Phase 1에서는 매 로그인마다 로그 저장해도 무방
기간/그룹 차단 로직 Phase 1에서는 제거. Phase 2에서 권한/상태만 적용

2.2 그대로 가져올 개념 (동작만 CI4로 구현)

항목 auth 종량제(CI4)
로그인 폼 mb_id, mb_passwd, return_url, token(CSRF) 동일. login_id, password, CI4 CSRF
회원 조회 member_m->login() → mb_id로 1건 UserModel::findByLoginId($loginId)
비밀번호 검증 password_verify() 동일
상태 체크 mb_state == 1 status 활성만 허용
성공 시 세션 userinfo, logged_in, (access_token) user(또는 userinfo), logged_in
로그인 로그 member_log insert (성공/실패) login_attempts 또는 audit_logs 에 INSERT
로그아웃 시 member_log에 logout 시각 update, 세션 destroy 로그아웃 로그 1건 INSERT + 세션 destroy
로그인 필수 체크 _require_login() → 없으면 /auth/logout Filter auth: 세션 없으면 redirect to /login

2.3 CI4에서 구현할 흐름 (Phase 1)

  1. GET /login

    • 이미 로그인됐으면 → /dashboard 리다이렉트
    • 아니면 로그인 뷰 표시 (auth의 login_v 참고해 레이아웃만 단순화)
  2. POST /login

    • Validation: login_id, password 필수
    • UserModel::findByLoginId(login_id)
    • 없으면 → 실패 로그 저장, "아이디 또는 비밀번호를 확인해 주세요." → 로그인 화면
    • 있으면 → password_verify(password, user->password_hash)
    • 실패 → 실패 로그, 동일 메시지
    • 활성 상태 아님 → "중지된 계정입니다." 등
    • 성공 →
      • 세션에 user(id, login_id, name, role 등), logged_in = true
      • 로그인 성공 로그 INSERT (IP, user_agent, user_id, success)
      • (선택) users.last_login_at UPDATE
      • redirect to /dashboard
  3. POST /logout

    • (선택) 로그아웃 로그 INSERT (user_id, action=LOGOUT)
    • session()->destroy()
    • redirect to /login
  4. Filter auth

    • URI가 login 이면 통과
    • 그 외: 세션에 logged_in 없으면 redirect to /login
    • 필요한 라우트에만 filter('auth') 적용 (또는 전역 적용 후 login만 제외)
  5. 대시보드

    • GET /dashboard → Filter auth 통과 후, 단순 대시 뷰 (나중에 Phase 2에서 admin 메뉴로 교체)

3. 정리

  • Auth의 로그인/로그아웃 플로우는 “폼 검증 → 회원 조회 → 비밀번호/상태 검사 → 세션 + 토큰 + 로그 기록 → 리다이렉트”이고, 로그아웃은 “토큰/로그 업데이트 + 세션 파기”입니다.
  • 종량제 Phase 1에서는 위 플로우 중 세션 기반 로그인/로그아웃 + 로그인(성공/실패) 로그만 동일하게 구현하고,
    JWT·access_token·3종 계정·Access 앱 선택 화면은 쓰지 않습니다.
  • 이렇게 하면 auth와 **동작 느낌(로그인 → 대시로 이동, 로그인 필수 구간 보호)**은 맞추면서, CI4 구조에 맞게 단순하게 가져갈 수 있습니다.

4. 회원가입 / 계정 생성 정책 (요구사항 기준 초안)

  • CSV와 현재 문서 기준으로 보면, 명시된 역할은 4가지입니다.
    • super admin / 지자체관리자 / 지정판매소 / 일반 사용자(시민)
  • 이 중에서 업무용 계정(super admin, 지자체, 지정판매소)
    • 관리자가 “사용자 관리(PWB-020201)” 화면에서 등록하고,
    • 브라우저에서 자체 등록한 계정이 있다면 권한 승인(PWB-020301) 으로 승인하는 흐름을 사용합니다.
  • 일반 사용자(시민) 는 현재 요구사항에서 로그인 기반 기능이 “정품 바코드 확인” 정도 뿐이고, “시민이 직접 회원가입해야 한다”는 명시는 없습니다.
  • 따라서 지금 요구사항만 놓고 보면:
    • 일반 사용자는 필수 회원가입 없이 앱을 쓸 수 있게 하고,
    • 관리자·지자체·지정판매소 계정은 관리자 등록 + (옵션) 권한 승인 구조로 가는 것이 자연스럽습니다.
  • 시민 회원가입/로그인(예: 마이페이지, 신고 이력 관리 등)이 실제로 필요해지는 시점에, 별도의 시민 회원가입/인증 플로우를 설계하는 쪽이 더 안전합니다.