DOCS/troubleshooting/250831_slack_oauth_login_implementation.md
happybell80 8c02b80359 Fix incorrect table names in documentation
- gmail_tokens → gmail_token (33 files)
- companies → company (17 files)
- conversation_logs → conversation_log (27 files)
- workspace_members → workspace_member (28 files)

All table names now match the actual PostgreSQL schema
2025-09-26 00:49:47 +09:00

138 lines
4.0 KiB
Markdown

# 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 스키마 불일치 ⚠️
**문제점**:
- `company` 테이블과 `workspaces` 테이블이 공존
- `SlackWorkspace` 모델이 `company_id`를 참조하는데 모델은 `workspace_id` 기대
- Relationship 주석 처리로 임시 해결
**현재 상태**:
```python
# app/models/workspace.py
class SlackWorkspace(Base):
company_id = Column(UUID, ForeignKey("company.id")) # 실제 DB
# workspace_id로 되어야 하는데 company 테이블 참조 중
# relationship 주석 처리됨
```
**해결 방안**:
1. `company` 테이블 데이터를 `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 스키마 통일 (company → 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
```