# 회원 관리 및 인증 시스템 구축 완료 ✅ ## 📝 작업 요약 부산교통공사 1호선 고장코드 시스템에 회원 관리 및 인증 기능을 성공적으로 추가했습니다. --- ## 🎯 구현된 기능 ### 1. **이메일 인증 시스템** - ✅ Supabase Auth를 활용한 이메일 기반 회원가입 및 로그인 - ✅ **humetro.busan.kr** 도메인만 허용하는 이메일 검증 - ✅ 비밀번호 암호화 및 안전한 인증 처리 ### 2. **회원가입 기능** - ✅ 사번, 이름, 소속부서, 이메일 정보 수집 - ✅ 부서 선택은 미리 정의된 부서 목록에서만 가능 - ✅ 이메일 도메인 자동 검증 - ✅ 비밀번호 확인 및 유효성 검사 ### 3. **부서별 권한 관리 기반 구축** - ✅ 부서 테이블 및 권한 테이블 설계 - ✅ 향후 부서별 조회/수정/삭제 권한 제어 가능 - ✅ RLS(Row Level Security) 정책 설정 --- ## 📂 생성된 파일 ### 1. **auth.py** - 인증 모듈 회원 관리 및 인증 로직을 담당하는 별도 모듈 **주요 클래스: AuthManager** - `validate_email()`: 이메일 도메인 검증 (humetro.busan.kr) - `get_departments()`: 가입 가능한 부서 목록 조회 - `signup_user()`: 회원가입 처리 (Supabase Auth + users 테이블) - `login_user()`: 로그인 처리 및 세션 데이터 생성 - `logout_user()`: 로그아웃 처리 - `check_email_exists()`: 이메일 중복 체크 - `check_employee_id_exists()`: 사번 중복 체크 ### 2. **database_schema.sql** - 데이터베이스 DDL Supabase에서 실행할 데이터베이스 스키마 정의 **생성되는 테이블:** #### 📋 departments (부서) ```sql - id (SERIAL PRIMARY KEY) - code (VARCHAR, UNIQUE) - 부서 코드 - name (VARCHAR) - 부서명 - description (TEXT) - 부서 설명 - is_active (BOOLEAN) - 활성화 여부 - created_at, updated_at (TIMESTAMPTZ) ``` **초기 부서 데이터:** - SPC: 신평차량 - NPC: 노포차량 - VHD: 차량처 > **참고**: 부서 목록은 Supabase의 `public.departments` 테이블에서 동적으로 관리됩니다. #### 👤 users (사용자) ```sql - id (SERIAL PRIMARY KEY) - auth_id (UUID, UNIQUE) - Supabase Auth ID - email (VARCHAR, UNIQUE) - 이메일 - employee_id (VARCHAR, UNIQUE) - 사번 - name (VARCHAR) - 이름 - department_id (INTEGER, FK) - 부서 ID - is_active (BOOLEAN) - 계정 활성화 여부 - last_login_at (TIMESTAMPTZ) - 마지막 로그인 - created_at, updated_at (TIMESTAMPTZ) ``` #### 🔐 department_permissions (부서별 권한) ```sql - id (SERIAL PRIMARY KEY) - department_id (INTEGER, FK) - resource_type (VARCHAR) - 'fault_code', 'signal', 'mmi_code' - can_read (BOOLEAN) - 조회 권한 - can_write (BOOLEAN) - 수정 권한 - can_delete (BOOLEAN) - 삭제 권한 - created_at, updated_at (TIMESTAMPTZ) ``` #### 📊 audit_logs (감사 로그) ```sql - id (SERIAL PRIMARY KEY) - user_id (INTEGER, FK) - action (VARCHAR) - 'login', 'logout', 'create', 'update', 'delete' - resource_type (VARCHAR) - resource_id (VARCHAR) - details (JSONB) - ip_address (VARCHAR) - created_at (TIMESTAMPTZ) ``` **추가 기능:** - ✅ RLS(Row Level Security) 정책 적용 - ✅ 트리거를 통한 updated_at 자동 업데이트 - ✅ 인덱스 최적화 - ✅ 뷰(users_with_department) 생성 ### 3. **templates/login.html** - 로그인 페이지 - 이메일/비밀번호 입력 폼 - 회원가입 페이지 링크 - 에러/성공 메시지 표시 - 반응형 디자인 (Pico CSS) ### 4. **templates/signup.html** - 회원가입 페이지 - 사번, 이름, 부서, 이메일, 비밀번호 입력 폼 - 부서 선택 드롭다운 (Supabase에서 동적으로 로드) - 이메일 도메인 검증 (humetro.busan.kr) - 비밀번호 확인 검증 - 에러 메시지 표시 ### 5. **app.py** - 수정된 메인 애플리케이션 **추가된 기능:** - Flask 세션 설정 (SECRET_KEY, 쿠키 보안) - 인증 라우트 추가: - `/auth/login` (GET, POST): 로그인 - `/auth/signup` (GET, POST): 회원가입 - `/auth/logout`: 로그아웃 - `@login_required` 데코레이터: 로그인 필요 페이지 보호 - `get_current_user()` 함수: 현재 로그인 사용자 정보 조회 ### 6. **templates/index.html** - 수정된 메인 페이지 - 헤더에 사용자 정보 표시 (이름, 사번) - 로그아웃 버튼 추가 - 로그인된 사용자만 접근 가능 ### 7. **AUTH_SETUP.md** - 설정 가이드 상세한 설정 및 사용 방법 문서 --- ## 🚀 설정 방법 (빠른 시작) ### 1단계: 데이터베이스 스키마 적용 Supabase SQL 에디터에서 실행: ```bash # database_schema.sql 파일 내용 복사 후 실행 ``` ### 2단계: 환경 변수 설정 `.env` 파일에 추가: ```bash # Supabase 설정 SUPABASE_URL=http://localhost:8000 SUPABASE_ANON_KEY=your-anon-key-here # Flask 세션 보안 키 (반드시 변경!) SECRET_KEY=your-secret-key-here ``` ### 3단계: 서버 실행 ```bash python app.py ``` ### 4단계: 회원가입 및 로그인 1. 브라우저에서 `http://localhost:5000` 접속 2. 자동으로 로그인 페이지로 리다이렉트 3. "회원가입" 클릭하여 계정 생성 4. humetro.busan.kr 도메인 이메일로 가입 --- ## 🔑 주요 보안 기능 ### 1. 이메일 도메인 제한 (애플리케이션 레벨) > ⚠️ **Docker 기반 Supabase 환경**: 대시보드 Authentication 설정이 제한적이므로, **애플리케이션 레벨에서만** 도메인 검증을 수행합니다. - **검증 위치**: `auth.py`의 `validate_email()` 함수 - **검증 패턴**: `@humetro.busan.kr`로 끝나는 이메일만 허용 ```python def validate_email(self, email: str) -> tuple[bool, str]: domain = email.split('@')[1] if domain != self.ALLOWED_EMAIL_DOMAIN: return False, f"{self.ALLOWED_EMAIL_DOMAIN} 도메인의 이메일만 사용 가능합니다." return True, "OK" ``` ### 2. 중복 검사 - 이메일 중복 체크 - 사번 중복 체크 ### 3. 세션 보안 - HTTPOnly 쿠키 - SameSite 설정 - SECRET_KEY 암호화 ### 4. Row Level Security (RLS) - 사용자는 본인 정보만 조회/수정 가능 - 부서 정보는 모든 인증된 사용자가 조회 가능 --- ## 📊 데이터베이스 관계도 ``` departments (부서) ↓ (1:N) users (사용자) ← auth_id → Supabase Auth ↓ department_permissions (부서별 권한) ↓ audit_logs (감사 로그) ``` --- ## 🎨 사용자 흐름 ### 회원가입 플로우 ``` 1. /auth/signup 접속 2. 부서 목록 로드 (Supabase departments 테이블) 3. 정보 입력 (사번, 이름, 부서, 이메일, 비밀번호) 4. 이메일 도메인 검증 (humetro.busan.kr) 5. Supabase Auth에 사용자 생성 6. users 테이블에 정보 저장 7. 로그인 페이지로 리다이렉트 ``` ### 로그인 플로우 ``` 1. /auth/login 접속 2. 이메일/비밀번호 입력 3. Supabase Auth 인증 4. users 테이블에서 사용자 정보 조회 5. 세션에 사용자 정보 저장 6. 메인 페이지로 리다이렉트 ``` ### 로그아웃 플로우 ``` 1. /auth/logout 접속 2. Supabase Auth 로그아웃 3. 세션 클리어 4. 로그인 페이지로 리다이렉트 ``` --- ## 🔍 API 엔드포인트 ### 인증 관련 - `GET /auth/login` - 로그인 페이지 - `POST /auth/login` - 로그인 처리 - `GET /auth/signup` - 회원가입 페이지 - `POST /auth/signup` - 회원가입 처리 - `GET /auth/logout` - 로그아웃 ### 메인 - `GET /` - 메인 페이지 (로그인 필요) --- ## 🛠️ 향후 확장 가능 사항 ### 1. 부서별 권한 적용 `department_permissions` 테이블을 활용하여: - 고장코드 조회/수정 권한 제어 - TCMS 신호 조회/수정 권한 제어 - MMI 코드 조회/수정 권한 제어 ### 2. 감사 로그 활용 `audit_logs` 테이블을 활용하여: - 사용자 활동 추적 - 데이터 수정 이력 관리 - 보안 모니터링 ### 3. 비밀번호 정책 강화 - 대문자, 숫자, 특수문자 포함 필수 - 비밀번호 변경 주기 설정 - 비밀번호 재사용 방지 ### 4. 2단계 인증 (2FA) - OTP 인증 추가 - SMS 인증 추가 ### 5. 관리자 페이지 - 사용자 관리 (활성화/비활성화) - 부서 관리 - 권한 관리 --- ## 📋 체크리스트 ### 설정 완료 확인 - [ ] `database_schema.sql` 실행 - [ ] `.env` 파일에 `SECRET_KEY` 설정 - [ ] Supabase Auth 이메일 인증 활성화 - [ ] 부서 데이터 확인 (`SELECT * FROM departments`) - [ ] 테스트 회원가입 수행 - [ ] 테스트 로그인 수행 ### 프로덕션 배포 전 - [ ] `SECRET_KEY` 변경 (강력한 랜덤 키) - [ ] HTTPS 활성화 - [ ] CORS 설정 검토 - [ ] Supabase 프로덕션 환경 설정 - [ ] 이메일 템플릿 커스터마이징 - [ ] 로그 모니터링 설정 --- ## 📚 관련 문서 - **AUTH_SETUP.md**: 상세 설정 가이드 및 트러블슈팅 - **database_schema.sql**: 데이터베이스 스키마 전체 - **auth.py**: 인증 모듈 소스 코드 --- ## 🤝 기술 스택 - **Backend**: Flask (Python) - **Authentication**: Supabase Auth - **Database**: Supabase (PostgreSQL) - **Frontend**: Pico CSS, HTMX - **Session**: Flask Session (서버 사이드) --- **작성일**: 2024년 10월 **부산교통공사 차량처** **1호선 고장코드 시스템 v2.0**