9.9 KiB
회원 관리 및 인증 시스템 설정 가이드
📋 개요
부산교통공사 1호선 고장코드 시스템에 회원 관리 및 인증 기능이 추가되었습니다.
주요 기능
- ✅ 이메일 인증: Supabase Auth를 사용한 이메일 기반 인증
- ✅ 도메인 제한: humetro.busan.kr 도메인만 가입 가능
- ✅ 부서별 관리: 부서 단위로 사용자 관리 및 권한 제어
- ✅ 세션 관리: Flask 세션을 통한 로그인 상태 유지
🗄️ 1. 데이터베이스 설정
1.1 Supabase SQL 에디터에서 스키마 생성
database_schema.sql 파일의 내용을 Supabase SQL 에디터에서 실행하세요.
# 파일 위치
./database_schema.sql
이 스크립트는 다음 테이블을 생성합니다:
- departments: 부서 정보
- users: 사용자 정보
- department_permissions: 부서별 권한 (조회/수정/삭제)
- audit_logs: 감사 로그 (선택사항)
1.2 초기 부서 데이터
스크립트 실행 시 다음 부서가 자동으로 생성됩니다:
| 코드 | 부서명 | 설명 |
|---|---|---|
| SPC | 신평차량 | 신평차량사업소 |
| NPC | 노포차량 | 노포차량사업소 |
| VHD | 차량처 | 차량처 |
참고: 추가 부서가 필요한 경우 Supabase에서 직접 추가하거나 관리자 페이지를 통해 관리할 수 있습니다.
추가 부서가 필요한 경우:
INSERT INTO public.departments (code, name, description)
VALUES ('NEW001', '새로운부서', '부서 설명');
🔐 2. Supabase Auth 설정
2.1 Docker 기반 Supabase 환경
⚠️ 중요: Docker 기반 Supabase를 사용하는 경우, 대시보드의 Authentication 설정이 제한적입니다.
따라서 애플리케이션 레벨에서만 이메일 도메인 검증을 수행합니다.
2.2 이메일 도메인 검증 (애플리케이션 레벨)
auth.py 모듈에서 자동으로 처리됩니다:
# 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 서비스가 활성화되어 있는지 확인
# Supabase 상태 확인
docker ps | grep supabase
⚙️ 3. 환경 변수 설정
3.1 Flask 백엔드 .env 파일 위치
⚠️ 중요:
SECRET_KEY는 Flask 백엔드의.env파일에 설정해야 합니다!
파일 위치: /home/ckh08045/Tr_Code/.env (app.py가 있는 디렉토리)
# 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 생성:
import secrets
print(secrets.token_hex(32))
생성된 키를 Flask 백엔드 .env 파일의 SECRET_KEY에 설정하세요.
3.3 프론트엔드와 백엔드 .env 구분
Flask 백엔드 .env (/home/ckh08045/Tr_Code/.env):
SUPABASE_URLSUPABASE_ANON_KEYSECRET_KEY← 여기에 설정!SUPABASE_BASIC_USERSUPABASE_BASIC_PASSWORD
TWA 프론트엔드 .env (/home/ckh08045/Tr_Code/twa-frontend/.env):
- Vue.js 관련 설정
- API 엔드포인트 등
SECRET_KEY는 필요 없음
🚀 4. 애플리케이션 실행
4.1 의존성 설치
pip install -r requirements.txt
4.2 서버 실행
python app.py
서버가 http://localhost:5000에서 실행됩니다.
📱 5. 사용 방법
5.1 회원가입
-
브라우저에서
http://localhost:5000접속 -
자동으로 로그인 페이지로 리다이렉트됨
-
회원가입 버튼 클릭
-
다음 정보 입력:
- 사번
- 이름
- 소속 부서 (드롭다운에서 선택)
- 이메일 (humetro.busan.kr 도메인만)
- 비밀번호 (최소 8자)
-
회원가입 완료 후 이메일 인증 (Supabase Auth 설정에 따라)
5.2 로그인
- 등록한 이메일과 비밀번호로 로그인
- 로그인 성공 시 메인 페이지로 이동
- 헤더에 사용자 이름과 사번 표시
5.3 로그아웃
- 헤더의 로그아웃 버튼 클릭
🔑 6. 권한 관리 (향후 확장)
6.1 부서별 권한 조회
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 권한 수정
UPDATE public.department_permissions
SET can_write = true
WHERE department_id = 1 AND resource_type = 'fault_code';
6.3 애플리케이션에서 권한 체크 (예시)
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): 부서 IDcode: 부서 코드 (UNIQUE)name: 부서명description: 설명is_active: 활성화 여부created_at,updated_at: 타임스탬프
users (사용자)
id(PK): 사용자 IDauth_id: Supabase Auth 사용자 ID (UNIQUE)email: 이메일 (UNIQUE)employee_id: 사번 (UNIQUE)name: 이름department_id(FK): 부서 IDis_active: 계정 활성화 여부last_login_at: 마지막 로그인 시각created_at,updated_at: 타임스탬프
department_permissions (부서별 권한)
id(PK): 권한 IDdepartment_id(FK): 부서 IDresource_type: 리소스 타입 ('fault_code', 'signal', 'mmi_code')can_read: 조회 권한can_write: 수정 권한can_delete: 삭제 권한created_at,updated_at: 타임스탬프
🔍 8. 트러블슈팅
8.1 로그인 실패
증상: "이메일 또는 비밀번호가 올바르지 않습니다."
해결 방법:
- 이메일 주소가
@humetro.busan.kr로 끝나는지 확인 - 비밀번호가 8자 이상인지 확인
- Supabase Auth가 활성화되어 있는지 확인
users테이블에 사용자가 존재하는지 확인:SELECT * FROM public.users WHERE email = 'user@humetro.busan.kr';
8.2 회원가입 실패
증상: "회원가입에 실패했습니다."
해결 방법:
- Supabase Auth가 활성화되어 있는지 확인
- 이메일이 이미 등록되어 있는지 확인
- 사번이 중복되지 않는지 확인
departments테이블에 부서가 존재하는지 확인
8.3 부서 목록이 표시되지 않음
증상: 회원가입 페이지에서 부서 선택 드롭다운이 비어있음
해결 방법:
database_schema.sql이 정상적으로 실행되었는지 확인departments테이블에 데이터가 있는지 확인:SELECT * FROM public.departments WHERE is_active = true;
8.4 세션이 유지되지 않음
증상: 페이지를 새로고침하면 로그인이 풀림
해결 방법:
.env파일에SECRET_KEY가 설정되어 있는지 확인- 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
부산교통공사 차량처