docs: add project docs and test updates
This commit is contained in:
164
docs/기본 개발계획/11-login-logout-development-guide.md
Normal file
164
docs/기본 개발계획/11-login-logout-development-guide.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# 로그인/로그아웃 개발 진행 가이드
|
||||
|
||||
기존 정리 문서(`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 토큰으로 로그인 폼 제출 동작
|
||||
|
||||
이 순서와 스펙대로 구현하면, 기존 정리 문서와 새로 추가된 요구사항을 모두 반영한 로그인/로그아웃 개발이 가능하다.
|
||||
Reference in New Issue
Block a user