# 회원 관리 및 인증 시스템 설정 가이드 ## 📋 개요 부산교통공사 1호선 고장코드 시스템에 회원 관리 및 인증 기능이 추가되었습니다. ### 주요 기능 - ✅ **이메일 인증**: Supabase Auth를 사용한 이메일 기반 인증 - ✅ **도메인 제한**: humetro.busan.kr 도메인만 가입 가능 - ✅ **부서별 관리**: 부서 단위로 사용자 관리 및 권한 제어 - ✅ **세션 관리**: Flask 세션을 통한 로그인 상태 유지 --- ## 🗄️ 1. 데이터베이스 설정 ### 1.1 Supabase SQL 에디터에서 스키마 생성 `database_schema.sql` 파일의 내용을 Supabase SQL 에디터에서 실행하세요. ```bash # 파일 위치 ./database_schema.sql ``` 이 스크립트는 다음 테이블을 생성합니다: - **departments**: 부서 정보 - **users**: 사용자 정보 - **department_permissions**: 부서별 권한 (조회/수정/삭제) - **audit_logs**: 감사 로그 (선택사항) ### 1.2 초기 부서 데이터 스크립트 실행 시 다음 부서가 자동으로 생성됩니다: | 코드 | 부서명 | 설명 | |------|--------|------| | SPC | 신평차량 | 신평차량사업소 | | NPC | 노포차량 | 노포차량사업소 | | VHD | 차량처 | 차량처 | > **참고**: 추가 부서가 필요한 경우 Supabase에서 직접 추가하거나 관리자 페이지를 통해 관리할 수 있습니다. **추가 부서가 필요한 경우**: ```sql INSERT INTO public.departments (code, name, description) VALUES ('NEW001', '새로운부서', '부서 설명'); ``` --- ## 🔐 2. Supabase Auth 설정 ### 2.1 Docker 기반 Supabase 환경 > ⚠️ **중요**: Docker 기반 Supabase를 사용하는 경우, 대시보드의 Authentication 설정이 제한적입니다. > > 따라서 **애플리케이션 레벨에서만 이메일 도메인 검증**을 수행합니다. ### 2.2 이메일 도메인 검증 (애플리케이션 레벨) `auth.py` 모듈에서 자동으로 처리됩니다: ```python # humetro.busan.kr 도메인만 허용 ALLOWED_EMAIL_DOMAIN = "humetro.busan.kr" 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 Supabase Auth 기본 설정 확인 Docker Supabase에서 확인할 사항: - Supabase가 정상적으로 실행 중인지 확인 - Kong Gateway (기본 포트 8000)가 작동하는지 확인 - Auth 서비스가 활성화되어 있는지 확인 ```bash # Supabase 상태 확인 docker ps | grep supabase ``` --- ## ⚙️ 3. 환경 변수 설정 ### 3.1 Flask 백엔드 `.env` 파일 위치 > ⚠️ **중요**: `SECRET_KEY`는 **Flask 백엔드**의 `.env` 파일에 설정해야 합니다! **파일 위치**: `/home/ckh08045/Tr_Code/.env` (app.py가 있는 디렉토리) ```bash # Supabase 설정 SUPABASE_URL=http://localhost:8000 SUPABASE_ANON_KEY=your-anon-key-here # Flask 세션 보안 키 (프로덕션에서는 반드시 변경!) SECRET_KEY=your-secret-key-here-change-in-production # Kong Basic Auth (선택사항) SUPABASE_BASIC_USER= SUPABASE_BASIC_PASSWORD= ``` ### 3.2 SECRET_KEY 생성 Python으로 안전한 SECRET_KEY 생성: ```python import secrets print(secrets.token_hex(32)) ``` 생성된 키를 **Flask 백엔드 `.env`** 파일의 `SECRET_KEY`에 설정하세요. ### 3.3 프론트엔드와 백엔드 .env 구분 **Flask 백엔드 .env** (`/home/ckh08045/Tr_Code/.env`): - `SUPABASE_URL` - `SUPABASE_ANON_KEY` - `SECRET_KEY` ← **여기에 설정!** - `SUPABASE_BASIC_USER` - `SUPABASE_BASIC_PASSWORD` **TWA 프론트엔드 .env** (`/home/ckh08045/Tr_Code/twa-frontend/.env`): - Vue.js 관련 설정 - API 엔드포인트 등 - `SECRET_KEY`는 **필요 없음** --- ## 🚀 4. 애플리케이션 실행 ### 4.1 의존성 설치 ```bash pip install -r requirements.txt ``` ### 4.2 서버 실행 ```bash python app.py ``` 서버가 `http://localhost:5000`에서 실행됩니다. --- ## 📱 5. 사용 방법 ### 5.1 회원가입 1. 브라우저에서 `http://localhost:5000` 접속 2. 자동으로 로그인 페이지로 리다이렉트됨 3. **회원가입** 버튼 클릭 4. 다음 정보 입력: - 사번 - 이름 - 소속 부서 (드롭다운에서 선택) - 이메일 (humetro.busan.kr 도메인만) - 비밀번호 (최소 8자) 5. 회원가입 완료 후 이메일 인증 (Supabase Auth 설정에 따라) ### 5.2 로그인 1. 등록한 이메일과 비밀번호로 로그인 2. 로그인 성공 시 메인 페이지로 이동 3. 헤더에 사용자 이름과 사번 표시 ### 5.3 로그아웃 - 헤더의 **로그아웃** 버튼 클릭 --- ## 🔑 6. 권한 관리 (향후 확장) ### 6.1 부서별 권한 조회 ```sql SELECT d.name, dp.resource_type, dp.can_read, dp.can_write, dp.can_delete FROM public.department_permissions dp JOIN public.departments d ON dp.department_id = d.id WHERE d.code = 'SPC'; ``` ### 6.2 권한 수정 ```sql UPDATE public.department_permissions SET can_write = true WHERE department_id = 1 AND resource_type = 'fault_code'; ``` ### 6.3 애플리케이션에서 권한 체크 (예시) ```python def check_permission(user, resource_type, action): """ user: 현재 사용자 정보 resource_type: 'fault_code', 'signal', 'mmi_code' action: 'read', 'write', 'delete' """ with build_pg_client() as c: r = c.get( "/department_permissions", params={ "department_id": f"eq.{user['department_id']}", "resource_type": f"eq.{resource_type}" } ) r.raise_for_status() perms = r.json() if perms: return perms[0].get(f"can_{action}", False) return False ``` --- ## 📊 7. 데이터베이스 스키마 ### 7.1 테이블 구조 #### departments (부서) - `id` (PK): 부서 ID - `code`: 부서 코드 (UNIQUE) - `name`: 부서명 - `description`: 설명 - `is_active`: 활성화 여부 - `created_at`, `updated_at`: 타임스탬프 #### users (사용자) - `id` (PK): 사용자 ID - `auth_id`: Supabase Auth 사용자 ID (UNIQUE) - `email`: 이메일 (UNIQUE) - `employee_id`: 사번 (UNIQUE) - `name`: 이름 - `department_id` (FK): 부서 ID - `is_active`: 계정 활성화 여부 - `last_login_at`: 마지막 로그인 시각 - `created_at`, `updated_at`: 타임스탬프 #### department_permissions (부서별 권한) - `id` (PK): 권한 ID - `department_id` (FK): 부서 ID - `resource_type`: 리소스 타입 ('fault_code', 'signal', 'mmi_code') - `can_read`: 조회 권한 - `can_write`: 수정 권한 - `can_delete`: 삭제 권한 - `created_at`, `updated_at`: 타임스탬프 --- ## 🔍 8. 트러블슈팅 ### 8.1 로그인 실패 **증상**: "이메일 또는 비밀번호가 올바르지 않습니다." **해결 방법**: 1. 이메일 주소가 `@humetro.busan.kr`로 끝나는지 확인 2. 비밀번호가 8자 이상인지 확인 3. Supabase Auth가 활성화되어 있는지 확인 4. `users` 테이블에 사용자가 존재하는지 확인: ```sql SELECT * FROM public.users WHERE email = 'user@humetro.busan.kr'; ``` ### 8.2 회원가입 실패 **증상**: "회원가입에 실패했습니다." **해결 방법**: 1. Supabase Auth가 활성화되어 있는지 확인 2. 이메일이 이미 등록되어 있는지 확인 3. 사번이 중복되지 않는지 확인 4. `departments` 테이블에 부서가 존재하는지 확인 ### 8.3 부서 목록이 표시되지 않음 **증상**: 회원가입 페이지에서 부서 선택 드롭다운이 비어있음 **해결 방법**: 1. `database_schema.sql`이 정상적으로 실행되었는지 확인 2. `departments` 테이블에 데이터가 있는지 확인: ```sql SELECT * FROM public.departments WHERE is_active = true; ``` ### 8.4 세션이 유지되지 않음 **증상**: 페이지를 새로고침하면 로그인이 풀림 **해결 방법**: 1. `.env` 파일에 `SECRET_KEY`가 설정되어 있는지 확인 2. Flask 앱이 세션 쿠키를 설정할 수 있는지 확인 (HTTPS/HTTP 설정) --- ## 🛡️ 9. 보안 고려사항 ### 9.1 프로덕션 체크리스트 - [ ] `SECRET_KEY` 변경 (절대 기본값 사용 금지) - [ ] HTTPS 사용 - [ ] Supabase RLS(Row Level Security) 활성화 - [ ] 비밀번호 정책 강화 (대문자, 숫자, 특수문자 포함) - [ ] 세션 타임아웃 설정 - [ ] CORS 설정 검토 (프로덕션에서는 특정 도메인만 허용) - [ ] 로그 모니터링 (`audit_logs` 테이블 활용) ### 9.2 RLS 정책 (이미 적용됨) `database_schema.sql`에 다음 RLS 정책이 포함되어 있습니다: - 부서 목록은 모든 인증된 사용자가 조회 가능 - 사용자는 본인 정보만 조회/수정 가능 --- ## 📚 10. 참고 자료 ### 10.1 파일 구조 ``` Tr_Code/ ├── app.py # 메인 애플리케이션 (인증 라우트 포함) ├── auth.py # 인증 모듈 (AuthManager 클래스) ├── database_schema.sql # 데이터베이스 스키마 ├── templates/ │ ├── index.html # 메인 페이지 (로그인 필요) │ ├── login.html # 로그인 페이지 │ └── signup.html # 회원가입 페이지 └── .env # 환경 변수 설정 ``` ### 10.2 핵심 모듈 #### `auth.py` - AuthManager 클래스 - `validate_email()`: 이메일 도메인 검증 - `get_departments()`: 부서 목록 조회 - `signup_user()`: 회원가입 처리 - `login_user()`: 로그인 처리 - `logout_user()`: 로그아웃 처리 #### `app.py` - 인증 라우트 - `/auth/login`: 로그인 페이지 및 처리 - `/auth/signup`: 회원가입 페이지 및 처리 - `/auth/logout`: 로그아웃 처리 - `/`: 메인 페이지 (로그인 필요) --- ## 🤝 11. 문의 및 지원 시스템 관련 문의사항은 차량처 시스템 관리자에게 연락하세요. --- **작성일**: 2024년 10월 **버전**: 1.0 **부산교통공사 차량처**