From d35fb987116d7cf8a120edcf7ed7033fd1f1cffd Mon Sep 17 00:00:00 2001 From: 0914eagle <0914eagle@gmail.com> Date: Sun, 31 Aug 2025 16:06:16 +0900 Subject: [PATCH] =?UTF-8?q?=EC=8A=AC=EB=A0=89=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 300_architecture/380_authentication_system.md | 175 ++++++++++++ plans/250831_todo_and_tech_debt.md | 253 ++++++++++++++++++ ...250831_slack_oauth_login_implementation.md | 138 ++++++++++ 3 files changed, 566 insertions(+) create mode 100644 300_architecture/380_authentication_system.md create mode 100644 plans/250831_todo_and_tech_debt.md create mode 100644 troubleshooting/250831_slack_oauth_login_implementation.md diff --git a/300_architecture/380_authentication_system.md b/300_architecture/380_authentication_system.md new file mode 100644 index 0000000..cd077c3 --- /dev/null +++ b/300_architecture/380_authentication_system.md @@ -0,0 +1,175 @@ +# 통합 인증 시스템 아키텍처 + +## 개요 +로빙 서비스의 통합 인증 시스템으로 Gmail, Slack 등 다양한 OAuth 제공자를 지원합니다. + +## 시스템 구성 + +### 1. Auth Server (포트 9000) +- **위치**: `/home/admin/auth-server` +- **기술 스택**: FastAPI, PostgreSQL, Redis +- **주요 기능**: + - OAuth 2.0/OIDC 인증 + - JWT 토큰 발급 및 검증 + - 사용자 관리 + - 워크스페이스 권한 관리 + +### 2. 인증 제공자 (Providers) + +#### Gmail OAuth +- **엔드포인트**: `/auth/gmail/login` +- **콜백**: `/auth/gmail/callback` +- **특징**: + - 임시 코드 방식 (`/auth/verify`) + - Redis에 60초간 토큰 저장 + - JWT 토큰 30일 유효 + +#### Slack OAuth (OIDC) +- **엔드포인트**: `/auth/slack/login/` +- **콜백**: `/auth/slack/login/callback` +- **특징**: + - OIDC with form_post + - GET/POST 콜백 모두 지원 + - 하이브리드 사용자 매핑 + +### 3. 데이터베이스 구조 + +#### users 테이블 +```sql +- id: UUID (Primary Key) +- email: VARCHAR(255) UNIQUE +- username: VARCHAR(100) UNIQUE +- name: VARCHAR(255) +- created_at: TIMESTAMP +``` + +#### slack_user_mapping 테이블 +```sql +- slack_user_id: VARCHAR(100) +- slack_workspace_id: UUID +- user_id: UUID (FK → users.id) +- created_at: TIMESTAMP +- PRIMARY KEY (slack_user_id, slack_workspace_id) +``` + +#### gmail_tokens 테이블 +```sql +- id: UUID +- user_id: UUID (FK → users.id) +- access_token: TEXT (암호화 필요) +- refresh_token: TEXT +- expires_at: TIMESTAMP +``` + +### 4. 인증 플로우 + +```mermaid +sequenceDiagram + participant U as User + participant F as Frontend + participant A as Auth Server + participant O as OAuth Provider + participant R as Redis + participant D as Database + + U->>F: 로그인 클릭 + F->>A: GET /auth/{provider}/login + A->>R: state 저장 (CSRF 방지) + A->>O: Redirect to OAuth + O->>U: 권한 요청 + U->>O: 승인 + O->>A: POST/GET callback with code + A->>O: Exchange code for token + O->>A: Return user info + A->>D: 사용자 조회/생성 + A->>R: 임시 코드 저장 + A->>F: Redirect with temp code + F->>A: POST /auth/verify + A->>R: 코드 검증 + A->>F: Return JWT token + F->>F: localStorage 저장 +``` + +## 현재 구현 상태 + +### 완료된 기능 ✅ +- Gmail OAuth 로그인 +- Slack OIDC 로그인 +- JWT 토큰 발급 (30일) +- Redis 기반 state 관리 +- 사용자 자동 생성/연동 + +### 임시 해결책 ⚠️ +1. **Frontend-Backend 불일치** + - Frontend가 `/auth/verify` 방식 사용 + - Slack도 임시 코드 방식으로 맞춤 + +2. **DB 스키마 불일치** + - companies vs workspaces 테이블 공존 + - relationship 주석 처리 + +3. **하드코딩된 값** + - redirect_uri: "http://localhost:3000" + - callback_url: "https://auth.ro-being.com/..." + +## 보안 고려사항 + +### 구현된 보안 기능 +- CSRF 방지 (state 파라미터) +- 1회용 임시 코드 (60초 TTL) +- HTTPS only cookies +- JWT 서명 검증 + +### 추가 필요 사항 +- PKCE (Proof Key for Code Exchange) +- Refresh Token 구현 +- Rate Limiting +- 토큰 암호화 저장 + +## 환경 변수 + +### 필수 설정 +```env +# JWT +JWT_SECRET_KEY=your-secret-key +JWT_ALGORITHM=HS256 +JWT_EXPIRATION_DAYS=30 + +# Slack OAuth +SLACK_CLIENT_ID= +SLACK_CLIENT_SECRET= +SLACK_REDIRECT_URI= + +# Gmail OAuth +GMAIL_CLIENT_ID= +GMAIL_CLIENT_SECRET= +GMAIL_REDIRECT_URI= + +# Redis +REDIS_URL=redis://localhost:6379/0 + +# PostgreSQL +DATABASE_URL=postgresql://robeings:password@localhost/main_db +``` + +## 향후 개선 계획 + +### 단기 (1-2주) +1. DB 스키마 통일 (companies → workspaces) +2. Frontend 인증 방식 통일 +3. 환경변수 정리 + +### 중기 (1개월) +1. Refresh Token 구현 +2. 다중 OAuth 제공자 통합 관리 +3. 권한 시스템 고도화 + +### 장기 (3개월) +1. SSO (Single Sign-On) 구현 +2. 2FA (Two-Factor Authentication) +3. 감사 로그 시스템 + +## 관련 문서 +- [Slack OAuth 구현 상세](/home/heejae/DOCS/troubleshooting/250831_slack_oauth_login_implementation.md) +- [UUID 변환 시스템](./uuid_conversion_system.md) +- [Gateway Proxy Patterns](./gateway_proxy_patterns.md) \ No newline at end of file diff --git a/plans/250831_todo_and_tech_debt.md b/plans/250831_todo_and_tech_debt.md new file mode 100644 index 0000000..a7a672f --- /dev/null +++ b/plans/250831_todo_and_tech_debt.md @@ -0,0 +1,253 @@ +# TODO 및 기술 부채 정리 + +## 작성일: 2025년 8월 31일 + +## 1. 긴급 해결 필요 사항 🔴 + +### Git Merge Conflict 해결 +**영향받는 파일들**: +- `/home/admin/auth-server/app/providers/gmail_passport.py` (HEAD vs eaed063) +- `/home/admin/auth-server/app/providers/gmail.py` +- `/home/admin/auth-server/app/api/gmail_refresh.py` + +**충돌 내용**: +- HEAD: 최신 변경사항 (UUID/username 처리 개선) +- eaed063: rb8001 크론잡 트러블슈팅 관련 변경 + +**해결 방법**: +```bash +cd /home/admin/auth-server +git status +# 각 파일 수동 병합 필요 +git add . +git commit -m "fix: merge conflicts - Slack OAuth implementation" +``` + +### DB 스키마 불일치 +**문제**: +- `companies` 테이블 vs `workspaces` 테이블 공존 +- `SlackWorkspace` 모델이 잘못된 FK 참조 +- Relationship 주석 처리로 임시 해결 중 + +**현재 상태**: +```sql +-- 실제 DB +slack_workspaces.company_id → companies.id +workspace_members.workspace_id → workspaces.id + +-- 모델 파일 (잘못됨) +SlackWorkspace.workspace_id → workspaces.id (실제로는 company_id) +``` + +**해결 계획**: +1. 데이터 백업 +2. companies 데이터를 workspaces로 마이그레이션 +3. FK 관계 재설정 +4. 모델 파일 통일 + +## 2. 중요도 높음 🟡 + +### Frontend-Backend 인증 방식 불일치 +**현재 상태**: +- Frontend: Gmail 방식 (`/auth/verify` 임시 코드) +- Slack: JWT 직접 전달 계획 → 임시 코드로 변경 + +**영향**: +- 불필요한 Redis 호출 +- 60초 시간 제한 +- 복잡한 인증 플로우 + +**해결 방법**: +1. Frontend `auth-context.tsx` 수정 + - JWT 직접 처리 로직 구현 + - Provider별 분기 처리 +2. 또는 통합 인증 서비스 구현 + +### 하드코딩된 설정값 +**위치 및 내용**: +```python +# /home/admin/auth-server/app/providers/slack.py +redirect_uri = "http://localhost:3000" # 하드코딩 +login_callback_url = "https://auth.ro-being.com/auth/slack/login/callback" + +# docker-compose.yml +DATABASE_URL=postgresql://robeings:robeings@192.168.219.45/main_db +``` + +**해결**: +- `.env` 파일로 이동 +- 환경별 설정 분리 (dev/staging/prod) + +## 3. 개선 사항 🟢 + +### 코드 품질 +1. **에러 처리 개선** + - 구체적인 에러 메시지 + - 사용자 친화적 에러 페이지 + - 로깅 강화 + +2. **테스트 추가** + - 단위 테스트 + - 통합 테스트 + - E2E 테스트 + +3. **문서화** + - API 문서 (OpenAPI/Swagger) + - 시퀀스 다이어그램 + - 배포 가이드 + +### 보안 강화 +1. **토큰 관리** + - Refresh Token 구현 + - 토큰 암호화 저장 + - Rate Limiting + +2. **OAuth 개선** + - PKCE 구현 + - State 파라미터 강화 + - Nonce 추가 + +## 4. 장기 로드맵 📅 + +### Q4 2025 +- [ ] DB 스키마 통일 +- [ ] Frontend 인증 방식 통일 +- [ ] 환경변수 정리 +- [ ] Git 충돌 해결 + +### Q1 2026 +- [ ] Multi-tenant 아키텍처 +- [ ] SSO 구현 +- [ ] 2FA 지원 +- [ ] 감사 로그 + +### Q2 2026 +- [ ] 마이크로서비스 분리 +- [ ] API Gateway 도입 +- [ ] 중앙 인증 서버 +- [ ] 모니터링 대시보드 + +## 5. 현재 작업 중인 파일 목록 + +### 수정된 파일 (commit 필요) +```bash +/home/admin/auth-server/ +├── app/ +│ ├── api/gmail_refresh.py (CONFLICT) +│ ├── models/workspace.py +│ ├── providers/ +│ │ ├── gmail.py (CONFLICT) +│ │ ├── gmail_passport.py (CONFLICT) +│ │ └── slack.py (NEW IMPLEMENTATION) +├── docker-compose.yml +└── tokens/unknown_gmail.json + +/home/heejae/frontend-customer/ +└── src/contexts/auth-context.tsx +``` + +### 신규 생성된 문서 +```bash +/home/heejae/DOCS/ +├── troubleshooting/ +│ └── 250831_slack_oauth_login_implementation.md +├── 300_architecture/ +│ └── 380_authentication_system.md +└── plans/ + └── 250831_todo_and_tech_debt.md (this file) +``` + +## 6. 명령어 참조 + +### Docker 관련 +```bash +# Auth server 재시작 +cd /home/admin/auth-server +docker compose down && docker compose up -d --build + +# 로그 확인 +docker logs auth-server --tail 100 -f +docker logs auth-redis --tail 50 +``` + +### Git 관련 +```bash +# 충돌 해결 +git status +git diff +git add +git commit -m "fix: resolve conflicts" + +# 변경사항 확인 +git log --oneline -10 +git diff HEAD~1 +``` + +### DB 관련 +```bash +# PostgreSQL 접속 +PGPASSWORD=robeings psql -h localhost -U robeings -d main_db + +# 테이블 구조 확인 +\d companies +\d workspaces +\d slack_workspaces +\d users +\d slack_user_mapping + +# 데이터 확인 +SELECT * FROM companies; +SELECT * FROM workspaces; +SELECT * FROM slack_workspaces; +``` + +### Redis 관련 +```bash +# Redis CLI +docker exec -it auth-redis redis-cli + +# Keys 확인 +KEYS oauth:state:* +KEYS auth:temp:* + +# TTL 확인 +TTL oauth:state: +``` + +## 7. 연락처 및 참고 + +### 관련 시스템 +- Auth Server: https://auth.ro-being.com (포트 9000) +- Frontend: https://ro-being.com (포트 3000) +- Gitea: https://git.ro-being.com +- PostgreSQL: 192.168.219.45:5432 +- Redis: localhost:6379 + +### 환경변수 위치 +- `/home/admin/auth-server/.env` +- `/home/heejae/frontend-customer/.env` + +### 주요 문서 +- [Slack OAuth 구현 상세](./troubleshooting/250831_slack_oauth_login_implementation.md) +- [인증 시스템 아키텍처](./300_architecture/380_authentication_system.md) +- [UUID 변환 시스템](./300_architecture/uuid_conversion_system.md) + +## 8. 체크리스트 + +### 배포 전 확인사항 +- [ ] Git 충돌 해결 +- [ ] 환경변수 설정 +- [ ] DB 마이그레이션 +- [ ] Docker 이미지 빌드 +- [ ] 로그 모니터링 +- [ ] 에러 처리 테스트 +- [ ] 롤백 계획 수립 + +### 테스트 시나리오 +- [ ] Gmail 로그인 +- [ ] Slack 로그인 +- [ ] 기존 사용자 연동 +- [ ] 신규 사용자 생성 +- [ ] 토큰 만료 처리 +- [ ] 에러 케이스 +- [ ] 동시 로그인 \ No newline at end of file diff --git a/troubleshooting/250831_slack_oauth_login_implementation.md b/troubleshooting/250831_slack_oauth_login_implementation.md new file mode 100644 index 0000000..0128288 --- /dev/null +++ b/troubleshooting/250831_slack_oauth_login_implementation.md @@ -0,0 +1,138 @@ +# Slack OAuth 로그인 구현 및 임시 해결책 정리 + +## 구현 날짜 +2025년 8월 31일 + +## 구현 내용 + +### 1. Slack OIDC 로그인 기능 구현 +- **엔드포인트**: `/auth/slack/login/` → `/auth/slack/login/callback` +- **인증 방식**: OAuth 2.0 with OIDC (OpenID Connect) +- **스코프**: `openid profile email` (공백 구분) +- **콜백 처리**: GET/POST 모두 지원 (Slack의 form_post 대응) + +### 2. 사용자 관리 로직 +- Slack에서 사용자 정보 획득 (email, name, picture, sub) +- 하이브리드 사용자 조회/생성: + 1. `slack_user_mapping` 테이블에서 기존 매핑 확인 + 2. 없으면 email로 기존 사용자 검색 + 3. 없으면 새 사용자 생성 +- UUID를 primary key로 사용 + +## 임시 해결책 및 기술 부채 + +### 1. DB 스키마 불일치 ⚠️ +**문제점**: +- `companies` 테이블과 `workspaces` 테이블이 공존 +- `SlackWorkspace` 모델이 `company_id`를 참조하는데 모델은 `workspace_id` 기대 +- Relationship 주석 처리로 임시 해결 + +**현재 상태**: +```python +# app/models/workspace.py +class SlackWorkspace(Base): + company_id = Column(UUID, ForeignKey("companies.id")) # 실제 DB + # workspace_id로 되어야 하는데 companies 테이블 참조 중 + # relationship 주석 처리됨 +``` + +**해결 방안**: +1. `companies` 테이블 데이터를 `workspaces`로 마이그레이션 +2. FK 관계 정리 +3. 모델 통일 + +### 2. Frontend-Backend 인증 방식 불일치 📝 +**문제점**: +- Frontend는 Gmail 방식 (`/auth/verify`) 사용 +- Slack 로그인은 원래 JWT 직접 전달 계획 +- 현재 Gmail과 동일한 임시 코드 방식으로 처리 + +**현재 구현**: +```python +# Slack 콜백에서 +temp_code = secrets.token_urlsafe(32) +await redis_client.setex(f"auth:temp:{temp_code}", 60, auth_data) +return RedirectResponse(url=f"{redirect_uri}#auth={temp_code}") + +# Frontend에서 +const authCode = hash.split('auth=')[1]; +fetch('/auth/verify', { body: { code: authCode } }) +``` + +**해결 방안**: +- Frontend를 JWT 직접 처리 방식으로 수정 +- 또는 통합 인증 컨텍스트 구현 + +### 3. 하드코딩된 설정 값들 📌 +**문제점**: +```python +redirect_uri = "http://localhost:3000" # 하드코딩 +login_callback_url = "https://auth.ro-being.com/auth/slack/login/callback" # 하드코딩 +``` + +**해결 방안**: +- 환경변수로 이동 +- 동적 리다이렉트 URL 처리 + +### 4. OIDC vs OAuth 2.0 혼란 🔄 +**시도한 방법들**: +1. OIDC (`/openid/connect/authorize`) - "Sign in with Slack" 필요 +2. OAuth 2.0 User Token (`user_scope`) - 작동하지만 다른 방식 +3. 최종: OIDC with form_post 지원 + +**주의사항**: +- Slack OIDC는 `response_modes_supported=["form_post"]` +- 콜백이 POST로 옴 (GET 아님) + +## 테스트된 사항 + +### 성공 ✅ +- Slack 로그인 플로우 완성 +- 사용자 정보 정상 획득 +- JWT 토큰 생성 및 발급 +- Frontend localStorage 저장 +- 기존 사용자 연동 (email 기준) + +### 알려진 이슈 ⚠️ +- 브라우저에 Slack 세션 있으면 자동 로그인 +- DB relationship 에러 (주석 처리로 회피) +- Frontend 빌드 캐시 문제 (강제 새로고침 필요) + +## 향후 작업 + +### 긴급도 높음 🔴 +1. DB 스키마 통일 (companies → workspaces) +2. Frontend 인증 방식 통일 + +### 중간 우선순위 🟡 +1. 환경변수 정리 +2. 에러 처리 개선 +3. 로깅 강화 + +### 낮은 우선순위 🟢 +1. OIDC ID token 검증 (JWKS) +2. refresh token 구현 +3. 로그아웃 시 Slack 세션 처리 + +## 관련 파일 +- `/home/admin/auth-server/app/providers/slack.py` +- `/home/admin/auth-server/app/models/workspace.py` +- `/home/heejae/frontend-customer/src/contexts/auth-context.tsx` +- `/home/admin/auth-server/app/routes/auth.py` + +## 참고 명령어 +```bash +# Docker 재시작 +cd /home/admin/auth-server +docker compose down && docker compose up -d --build + +# Frontend 빌드 +cd /home/heejae/frontend-customer +npm install && npm run build + +# 로그 확인 +docker logs auth-server --tail 50 + +# DB 확인 +PGPASSWORD=robeings psql -h localhost -U robeings -d main_db +``` \ No newline at end of file