슬렉 로그인
This commit is contained in:
parent
3030783ccb
commit
d35fb98711
175
300_architecture/380_authentication_system.md
Normal file
175
300_architecture/380_authentication_system.md
Normal file
@ -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)
|
||||
253
plans/250831_todo_and_tech_debt.md
Normal file
253
plans/250831_todo_and_tech_debt.md
Normal file
@ -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 <file>
|
||||
git add <file>
|
||||
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:<uuid>
|
||||
```
|
||||
|
||||
## 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 로그인
|
||||
- [ ] 기존 사용자 연동
|
||||
- [ ] 신규 사용자 생성
|
||||
- [ ] 토큰 만료 처리
|
||||
- [ ] 에러 케이스
|
||||
- [ ] 동시 로그인
|
||||
138
troubleshooting/250831_slack_oauth_login_implementation.md
Normal file
138
troubleshooting/250831_slack_oauth_login_implementation.md
Normal file
@ -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
|
||||
```
|
||||
Loading…
x
Reference in New Issue
Block a user