- 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
138 lines
4.0 KiB
Markdown
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
|
|
``` |