DOCS/ideas/auth_system_analysis.md
happybell80 b8765f44ae docs: Slack-Google 인증 통합 문제점 추가
- Slack OAuth와 Google OAuth 별개 운영 문제
- Slack 사용자 매핑 현황 (3개 하드코딩)
- 복잡한 관계 구조 및 권한 충돌 가능성
- 이메일 기반 자동 연결 전략 제안
- Phase 5 로드맵 추가
2025-08-16 11:11:51 +09:00

8.8 KiB

로빙 프로젝트 인증 시스템 전체 분석 및 통합 방안

현재 구조 분석

1. 데이터베이스 (PostgreSQL - auth_db)

Users 테이블 구조

- id: UUID (Primary Key)
- username: VARCHAR(50) UNIQUE  # happybell80 
- email: VARCHAR(255) UNIQUE NOT NULL
- name: VARCHAR(255)
- picture: VARCHAR(500)  # OAuth profile picture URL
- oauth_provider: VARCHAR(50)  # google, github 
- oauth_id: VARCHAR(255)  # Provider의 user ID
- is_active: BOOLEAN
- created_at, updated_at, last_login_at: TIMESTAMP

WorkspaceMembers 테이블

- user_id: UUID (FK to users.id)
- workspace_id: UUID
- robing_id: VARCHAR(100)  # rb8001, rb10508 
- role: ENUM (owner, member, guest)

2. Auth Server (51123 서버, 포트 9000)

JWT 토큰 구조

# 토큰 생성 시 페이로드 (gmail.py:183-188)
{
    "sub": username,        # "happybell80" - 주요 식별자
    "email": user_email,    # "goeun2dc@gmail.com"
    "name": user_name,      # "김고은"
    "username": username,   # "happybell80" (중복)
    "exp": expires_at
}

환경 변수

  • JWT_SECRET_KEY: ro-being-auth-jwt-secret-key-2024
  • JWT_ALGORITHM: HS256
  • JWT_ACCESS_TOKEN_EXPIRE_MINUTES: 30일

이메일-유저명 매핑 (하드코딩)

# gmail.py:150-154
email_to_username = {
    'goeun2dc@gmail.com': 'happybell80',
    'eagle0914@gmail.com': 'eagle0914',
}

3. Frontend (frontend-customer)

토큰 저장/조회

  • 저장 키: auth_token (auth-context.tsx:61)
  • 조회: localStorage.getItem('auth_token') (auth-context.tsx:29)
  • 서버 URL: https://auth.ro-being.com (하드코딩)

현재 문제점

// robing-api.ts - 토큰 전송 안함!
export async function sendMessage(text: string, userId: string = 'test_user') {
    // Authorization 헤더 없음
    // 모든 사용자가 'test_user'로 처리됨
}

4. Robing Gateway (포트 10100)

현재 처리 방식

# main.py:92-95
x_user_id: Optional[str] = Header(None)  # X-User-Id 헤더만 확인
# JWT 토큰 검증 없음!

5. Robing Services (51124 서버)

ChromaDB 컬렉션명 생성

# storage.py:84 (추정)
collection_name = f"{robing_id}_{user_id}_episodic"
# 현재: rb10508_test_default_episodic (모든 사용자 공유!)

주요 문제점

1. 인증 토큰 미전송 ⚠️

  • Frontend가 API 호출 시 JWT 토큰을 전송하지 않음
  • robing-api.ts에 Authorization 헤더 없음
  • 모든 사용자가 'test_user'로 처리

2. 백엔드 토큰 미검증 ⚠️

  • Robing Gateway가 JWT 토큰을 검증하지 않음
  • X-User-Id 헤더만 확인 (누구나 위조 가능)

3. 사용자 식별 실패 ⚠️

  • username이 제대로 전달되지 않아 'default'로 폴백
  • ChromaDB 컬렉션을 모든 사용자가 공유

4. 이메일-유저명 매핑 하드코딩 📝

  • 새 사용자 추가 시 코드 수정 필요
  • 확장성 없음

5. OAuth 권한 과다 요청 🔐

  • 회원가입/로그인 시 Gmail 읽기/쓰기 권한(gmail.modify)까지 요청
  • 복잡한 동의 과정으로 사용자 이탈 가능성 높음
  • 이메일 기능 미사용자에게도 과도한 권한 요청

6. 변수명 불일치 혼란 🔄

  • user_id vs username vs email 혼용
  • JWT의 'sub'가 username인지 user_id인지 불명확

7. Slack 통합과 인증 체계 불일치 🔗

  • Slack OAuth와 Google OAuth 별개 운영

    • Slack 워크스페이스 인증 (봇 토큰)
    • Google 개인 인증 (사용자 토큰)
    • 두 시스템 간 연결 고리 불명확
  • Slack 사용자 매핑 문제

    • slack_user_id (U0925SXQFDK) ↔ user_id (UUID) 매핑 필요
    • 현재 하드코딩된 매핑 3개만 존재
    • 신규 Slack 사용자 자동 연결 방법 없음
  • 복잡한 관계 구조

    Slack Workspace ← SlackWorkspaces 테이블
          ↓
    Slack User ID ← slack_user_mapping 테이블
          ↓
    User (UUID) ← users 테이블
          ↓
    Google Account (OAuth)
    
  • 권한 충돌 가능성

    • Slack 봇 권한: chat:write, channels:read 등
    • Google 권한: gmail.modify, calendar.events 등
    • 같은 사용자가 두 가지 인증 경로 보유

결정 필요 사항

1. 주요 식별자 선택

  • username (추천): 'happybell80' - 인간 친화적, URL 안전
  • user_id (UUID): 'a1b2c3d4-...' - DB 표준, 중복 없음
  • email: 'goeun2dc@gmail.com' - OAuth 표준, 변경 가능성

2. JWT 페이로드 표준화

옵션 A (username 중심):
{
    "sub": "happybell80",      // 주 식별자
    "user_id": "uuid-here",     // DB ID
    "email": "goeun2dc@gmail.com",
    "name": "김고은"
}

옵션 B (UUID 중심):
{
    "sub": "uuid-here",         // 주 식별자
    "username": "happybell80",
    "email": "goeun2dc@gmail.com",
    "name": "김고은"
}

3. API 헤더 표준화

옵션 A (Bearer 토큰만):
Authorization: Bearer <jwt_token>

옵션 B (Bearer + X-User-Id):
Authorization: Bearer <jwt_token>
X-User-Id: happybell80  // 빠른 조회용

옵션 C (Bearer + X-Username):
Authorization: Bearer <jwt_token>
X-Username: happybell80  // 명확한 이름

4. ChromaDB 컬렉션 네이밍

옵션 A: {robing_id}_{username}_episodic
예: rb10508_happybell80_episodic

옵션 B: {robing_id}_{user_uuid}_episodic
예: rb10508_a1b2c3d4_episodic

옵션 C: {workspace_id}_{robing_id}_{username}_episodic
예: workspace1_rb10508_happybell80_episodic

5. 토큰 저장 키 통일

현재: 'auth_token'
대안: 'jwt_token', 'access_token', 'robing_token'

6. OAuth 권한 분리 전략

# 옵션 A: 단계별 권한 요청 (추천) ✅
기본 로그인: openid, userinfo.email, userinfo.profile
이메일 스킬: gmail.modify (별도 연결)
캘린더 스킬: calendar.events (별도 연결)

# 옵션 B: 일괄 권한 요청 (현재)
모든 권한을  번에 요청 (사용자 이탈 높음)

구현 방안:

  • /auth/gmail/login - 기본 프로필 권한만 (간단한 로그인)
  • /auth/gmail/connect-email - Gmail 권한 추가 (이메일 아이템 사용 시)
  • DB에 권한 레벨 저장: oauth_scopes 필드 추가
  • Frontend에서 권한 상태 표시 및 추가 연결 버튼 제공

7. Slack과 Google 인증 통합 전략

옵션 A: 통합 인증 (하나의 주 계정)
- Google 로그인을 주 인증으로 사용
- Slack은 추가 연결 (선택적)
- 장점: 단순한 인증 흐름
- 단점: Slack 전용 사용자 지원 어려움

옵션 B: 독립 인증 (현재)
- Google과 Slack 각각 독립 인증
- 수동 매핑 필요
- 장점: 유연성
- 단점: 복잡한 관리

옵션 C: 자동 연결 (추천) ✅
- 이메일 기반 자동 매칭
- Slack 이메일 == Google 이메일 시 자동 연결
- 불일치 시 수동 연결 옵션 제공

구현 방안:

  • Slack 사용자가 처음 메시지 전송 시:
    1. Slack API로 이메일 조회
    2. users 테이블에서 같은 이메일 검색
    3. 매칭되면 자동으로 slack_user_mapping 생성
    4. 없으면 임시 계정 생성 후 연결 대기

즉시 수정 필요 (Critical)

1. Frontend (robing-api.ts)

// 토큰 전송 추가
const token = localStorage.getItem('auth_token');
headers['Authorization'] = `Bearer ${token}`;

2. Gateway (main.py)

# JWT 검증 추가
from app.core.auth import decode_access_token

authorization = Header(None)
if authorization:
    token = authorization.replace("Bearer ", "")
    payload = decode_access_token(token)
    username = payload.get("sub")  # 또는 username

3. Robing Service (storage.py)

# username 기반 컬렉션 생성
collection_name = f"{robing_id}_{username}_episodic"

단계별 구현 계획

Phase 1: 긴급 패치 (1일)

  1. Frontend에서 토큰 전송
  2. Gateway에서 토큰 검증
  3. username 기반 ChromaDB 분리

Phase 2: 표준화 (3일)

  1. 변수명 통일 (username vs user_id)
  2. JWT 페이로드 표준화
  3. API 문서 작성

Phase 3: 개선 (1주)

  1. 이메일-유저명 매핑 DB화
  2. 토큰 갱신 로직 구현
  3. 권한 체계 구현

Phase 4: OAuth 권한 분리 (1주)

  1. 기본 로그인용 엔드포인트 구현 (최소 권한)
  2. 스킬별 추가 권한 연결 엔드포인트 구현
  3. DB에 사용자별 권한 상태 저장
  4. Frontend에 권한 관리 UI 추가

Phase 5: Slack-Google 인증 통합 (2주)

  1. 이메일 기반 자동 매칭 로직 구현
  2. Slack 사용자 첫 메시지 시 자동 계정 생성
  3. 수동 연결 UI 개발
  4. 통합 대시보드 구현

참고 사항

  • JWT Secret: 모든 서비스가 같은 키 공유 필요
  • CORS 설정: frontend URL 추가 필요
  • Redis: 토큰 캐싱 및 세션 관리 활용
  • 로그: 모든 인증 실패 상세 로깅

문서 작성자

  • 작성일: 2025-08-16
  • 작성자: 51123 서버 관리 Claude
  • 목적: 인증 시스템 통합을 위한 현황 분석