# 로그인/로그아웃 개발 진행 가이드 기존 정리 문서(`06-development-plan.md`, `08-auth-login-flow-and-ci4-apply.md`)와 새로 추가된 요구사항(Notion 설계, 25.11.24 미팅, auth DB DDL)을 바탕으로 **로그인/로그아웃 기능을 어떤 순서로 어떻게 개발할지** 정리한 문서입니다. --- ## 1. 목적·범위 - **목적**: Phase 1 공통·인증의 핵심인 **로그인/로그아웃**을 구현하여, 이후 모든 화면에서 "로그인 필수" 체크와 권한 기반 메뉴(Phase 2)의 기반을 마련한다. - **범위**: - 로그인 화면(GET/POST), 로그아웃(POST), 세션 기반 인증 - 로그인 성공/실패/로그아웃 **이력 저장**(각 기능별 로그 필수 요구 반영, 향후 블록체인/불변 원장 확장 고려) - 로그인하지 않으면 내부 페이지 접근 불가(Filter) - **제외(Phase 1)**: - 2차 인증, 5회 실패 시 계정 lock → Phase 2에서 검토 - 회원가입 화면 → 관리자 사용자 관리(Phase 2)에서 계정 생성 - JWT·자동 로그인 --- ## 2. 참조 문서 | 문서 | 참고 내용 | |------|-----------| | `06-development-plan.md` | Phase 1 목표, Phase 2 이후 흐름, §7 운영 요구(로그 필수) | | `08-auth-login-flow-and-ci4-apply.md` | auth 로그인/로그아웃 플로우, CI4 적용 흐름(GET/POST login, logout, Filter), 회원가입 정책 | | `00-project-overview.md` | 4가지 권한(super admin, 지자체관리자, 지정판매소, 일반 사용자) | | auth DDL (회원 제공) | `member`, `member_log` 테이블 구조 — 종량제 DB와 **최대한 유사**하게 설계 | --- ## 3. DB 설계 (auth 유사) ### 3.1 테이블: `member` auth의 `member` DDL을 기준으로, 종량제에서 **로그인/권한에 필요한 컬럼만** 우선 반영한다. - **식별·계정**: `mb_idx`(PK), `mb_id`(UNIQUE), `mb_passwd`, `mb_type`(또는 `mb_level`/`mb_group`으로 역할 구분) - **기본 정보**: `mb_name`, `mb_email`, `mb_phone`, `mb_lang` - **권한**: `mb_level`, `mb_group` (또는 `mb_type` 하나로 super_admin / local_admin / shop / citizen 구분) - **상태·날짜**: `mb_state`(1 정상, 2 정지, 0 탈퇴), `mb_regdate`, `mb_latestdate`, `mb_leavedate`(NULL 가능) - **기타**: auth와 동일하게 두되, 유료회원/기간 제한 등은 Phase 1에서 미사용 가능 날짜 컬럼은 **VARCHAR → DATETIME** 로 통일해 두면 CI4에서 다루기 편하다. 마이그레이션 작성 시 auth DDL(`member`)을 참고해 `CREATE TABLE member ( ... )` 형태로 작성한다. ### 3.2 테이블: `member_log` auth의 `member_log` DDL을 참고해 **로그인/로그아웃 이력**을 저장한다. - **필수 컬럼**: `mll_idx`(PK), `mll_success`, `mb_idx`, `mb_id`, `mll_regdate`, `mll_ip`, `mll_msg`, `mll_useragent`, `mll_logout_date` - **선택**: `mll_url`, `mll_referer`, `mll_country`, `at_token` — Phase 1에서는 비워두거나 NULL 허용 - 엔진: **MyISAM → InnoDB** 로 생성해도 됨 로그인 시도(성공/실패) 시 1건 INSERT, 로그아웃 시 해당 세션의 마지막 로그인 로그에 `mll_logout_date` UPDATE 하거나, 로그아웃 시점에 새 로그 1건 INSERT 하는 방식 중 하나로 통일한다. (08 문서에서는 “로그아웃 로그 1건 INSERT”를 옵션으로 둠.) --- ### 3.3 로그 테이블 구분 정책 - **로그인/로그아웃 로그** → **전용 테이블 `member_log`** 에만 저장한다. - auth 호환·로그인 이력 조회(Phase 2의 "로그인 이력 조회")용으로 컬럼 구조(mb_idx, mll_success, mll_regdate, mll_logout_date 등)를 유지한다. - **그 외 기능에 대한 감사 로그**(입고·불출·판매·메뉴 접근·사용자 CRUD·권한 변경 등) → **별도 통합 테이블 한 개**에 저장한다. - 예: `audit_log` (또는 `action_log`) — 컬럼 예: `al_idx`, `mb_idx`, `action`(또는 `log_type`), `entity`, `entity_id`, `regdate`, `ip`, `user_agent`, `payload`(JSON) 등. - Phase 1에서는 `member_log`만 구현하고, `audit_log`는 Phase 2 이후 각 기능 개발 시점에 도입해도 된다. 즉, **로그인 로그만 `member_log`에 두고, 나머지 기능 로그는 같은 통합 테이블(`audit_log`)에 남기는 구조**로 한다. --- ## 4. 구현 순서 아래 순서대로 진행하면 의존 관계 없이 단계별로 검증할 수 있다. 1. **마이그레이션 작성 및 실행** - **Phase 1에서는 로그인 관련 테이블만** 생성: `member`, `member_log` (auth DDL 참고, charset/collate는 `utf8mb4`/`utf8mb4_unicode_ci` 권장). 그 외 테이블(menu, audit_log 등)은 해당 기능을 만들 때 마이그레이션으로 추가하면 된다. - `php spark migrate` 로 적용 2. **시더(Seeder) 작성** - 테스트용 **super admin** 계정 1건 (예: `mb_id` = admin, 비밀번호는 `password_hash` 로 저장) 3. **Config 설정** - `app/Config/Routes.php`: `get('login', ...)`, `post('login', ...)`, `post('logout', ...)`, `get('dashboard', ...)` 등 - `app/Config/Filters.php`: `auth` 필터 정의 (세션 없으면 redirect to `/login`), `guest` 필터(로그인 상태면 `/dashboard`로) - `app/Config/Validation.php`: 로그인 폼 규칙 (`login_id` 필수, `password` 필수·최소 길이) 4. **모델** - `App\Models\MemberModel`: `findByLoginId($loginId)`, `updateLastLoginAt($id)` 등 (auth `Member_m` 참고) - `App\Models\MemberLogModel`: `insertItem($data)`, (로그아웃 시) `updateLogoutByToken($token)` 또는 로그아웃 전용 `insertLogout($userId)` 등 5. **컨트롤러** - `App\Controllers\AuthController`: `showLoginForm()`, `login()`, `logout()` (08 §2.3 흐름 그대로) - `App\Controllers\DashboardController`: `index()` — 로그인 후 첫 화면(임시 뷰) 6. **Filter 적용** - `auth`: 로그인 필요 라우트에 적용 (또는 전역 적용 후 `/login` 제외) - `guest`: `/login` 접근 시 이미 로그인돼 있으면 `/dashboard` 로 리다이렉트 7. **뷰** - **로그인 화면** (`app/Views/auth/login.php`): 레이아웃 없이 **단독 페이지**로 구성. 아이디·비밀번호 입력 필드, CSRF hidden, 제출 버튼, 검증 실패 시 `validation_list_errors()` 또는 컨트롤러에서 넘긴 `error` 메시지 출력. auth의 `login_v` 참고해 단순화. Phase 1에서는 스타일은 최소(또는 CI4 기본 스타일)로 두고, Phase 2에서 admin 테마 적용 시 로그인 페이지만 공통 헤더 없이 유지. - **대시보드** (`app/Views/dashboard/index.php`): 로그인 후 첫 화면. Phase 1에서는 **최소 구성** — 상단에 로그인 사용자 표시 + 로그아웃 링크(폼 POST `/logout` 또는 링크), 본문은 "대시보드" 문구만 있어도 됨. Phase 2에서 admin 레이아웃(header + sidebar + 본문)을 도입하면 이 뷰를 레이아웃 본문으로 넣고, sidebar 메뉴는 그때 추가. - **공통 레이아웃**: Phase 1에서는 대시보드용 레이아웃을 따로 두지 않고, 단순 HTML로 로그아웃만 넣어도 됨. Phase 2에서 `layout_main_v` 스타일(header + sidebar)을 만들 때 `layout/header.php`, `layout/sidebar.php` 등을 도입하면 됨. 8. **동작 확인** - 미로그인 시 `/dashboard` 접근 → `/login` 이동 - 로그인 성공 → `/dashboard` 이동, 세션 유지 - 로그아웃 → 세션 제거 후 `/login` 이동 - `member_log` 에 성공/실패/로그아웃 기록 저장 여부 확인 --- ## 5. 상세 스펙 요약 - **GET /login** - 이미 로그인(`logged_in`)이면 `/dashboard` 리다이렉트 - 아니면 로그인 뷰 출력 (CSRF 토큰 포함) - **POST /login** - 입력: `login_id`, `password` - 검증 실패 → 로그인 뷰 + 에러 메시지 - `MemberModel::findByLoginId(login_id)` 없음 → 실패 로그 INSERT, "아이디 또는 비밀번호를 확인해 주세요." - `password_verify` 실패 → 실패 로그 INSERT, 동일 메시지 - `mb_state != 1` → "중지된 계정입니다." 등 - 성공 → 세션에 `user`(mb_idx, mb_id, mb_name, mb_level, mb_group 등), `logged_in = true` / 성공 로그 INSERT / `mb_latestdate` UPDATE / redirect to `/dashboard` - **POST /logout** - (선택) 로그아웃 이력 저장 (`member_log` 에 1건 추가 또는 기존 로그에 `mll_logout_date` UPDATE) - `session()->destroy()` 후 redirect to `/login` - **앱 첫 페이지** - 이 앱은 **공개 랜딩이 없고**, 비로그인 사용자가 보는 첫 화면은 **로그인 화면**만 둔다. 따라서 **루트 URL (`/`) 은 `/login`으로 리다이렉트**하거나, `/` 에서 바로 로그인 뷰를 출력하도록 한다. (현재 `Routes.php`의 `Home::index`는 구현 시 `/login` 리다이렉트로 교체.) - **Filter `auth`** - `logged_in` 없으면 redirect to `/login` - `login` URI는 통과(또는 `guest` 필터로 로그인 상태면 `/dashboard` 이동) --- ## 6. 역할(권한) 처리 - **Phase 1**에서는 `member` 테이블의 `mb_level`, `mb_group`(또는 `mb_type`)만 저장하고, **메뉴/기능 제어는 Phase 2(메뉴별 권한 설정)** 에서 구현한다. - 로그인 성공 시 세션에 `user.mb_level`, `user.mb_group` 등을 넣어 두어, Phase 2에서 sidebar·라우트 접근 제어에 사용하면 된다. - 4가지 역할은 `00-project-overview.md` 기준: super admin, 지자체관리자, 지정판매소, 일반 사용자 — DB에는 auth와 같이 `mb_level`/`mb_group` 코드로 구분하거나, `mb_type` enum 하나로 구분해도 됨. --- ## 7. 로그(감사 이력) 요구사항 반영 - 로그 테이블 구분은 **§3.3** 참고: 로그인/로그아웃 → `member_log` 전용, 그 외 기능 → `audit_log` 통합 테이블. - 25.11.24 미팅 및 06 §7에서 **각 기능별 로그 필요**가 명시되어 있으므로, 로그인/로그아웃에서도 **반드시 `member_log` 에 기록**한다. - 로그인 시도(성공/실패) 시 1건 INSERT, 로그아웃 시 1건 추가 또는 기존 로그에 로그아웃 시각 UPDATE. - 추후 블록체인/불변 원장 도입 시 이 로그가 기반 데이터가 될 수 있으므로, **INSERT 전용**으로 두고 UPDATE/DELETE는 하지 않는 정책을 권장한다. (로그아웃 시각만 UPDATE하는 방식은 예외로 둘 수 있음.) --- ## 8. 검증 체크리스트 - [ ] 미로그인 시 `/dashboard` 접근 시 `/login`으로 리다이렉트 - [ ] 잘못된 아이디/비밀번호 시 에러 메시지 및 실패 로그 1건 - [ ] 정상 로그인 시 세션 생성, `member_log` 성공 1건, `mb_latestdate` 갱신 - [ ] 로그아웃 시 세션 삭제, `/login` 리다이렉트, (선택) 로그아웃 기록 - [ ] 로그인 상태에서 `/login` 접근 시 `/dashboard`로 리다이렉트 - [ ] CSRF 토큰으로 로그인 폼 제출 동작 이 순서와 스펙대로 구현하면, 기존 정리 문서와 새로 추가된 요구사항을 모두 반영한 로그인/로그아웃 개발이 가능하다.