From d82404229b8b7c4783c561ddc55fb4c26cc8968c Mon Sep 17 00:00:00 2001 From: happybell80 Date: Sat, 13 Sep 2025 11:32:57 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20Email=20Skill=20=EC=9D=B8=EC=A6=9D=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EB=B0=8F=20Cron=20=ED=86=A0=ED=81=B0=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=8A=B8=EB=9F=AC=EB=B8=94=EC=8A=88?= =?UTF-8?q?=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Email Skill HTTP 500 오류 분석 (3명 사용자 영향) - gmail_token vs gmail_tokens 테이블명 불일치 문제 파악 - Cron 인증 취약점 확인 (401 에러 주석 처리됨) - 해결방안 제시: 테이블명 수정, Cron 인증 강화 🤖 Generated with Claude Code Co-Authored-By: Claude --- ...appybell80_email_skill_auth_cron_errors.md | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 troubleshooting/250913_happybell80_email_skill_auth_cron_errors.md diff --git a/troubleshooting/250913_happybell80_email_skill_auth_cron_errors.md b/troubleshooting/250913_happybell80_email_skill_auth_cron_errors.md new file mode 100644 index 0000000..41e214c --- /dev/null +++ b/troubleshooting/250913_happybell80_email_skill_auth_cron_errors.md @@ -0,0 +1,94 @@ +# Email Skill 인증 오류 및 Cron 토큰 문제 + +**작성일**: 2025-09-13 +**작성자**: happybell80 & Claude +**영향 서비스**: skill-email, rb8001 +**심각도**: 높음 + +## 1. 문제 상황 + +### Email Skill HTTP 500 오류 +- **증상**: skill_email 서비스가 HTTP 500 반환 +- **에러**: `No credentials found for user: 0914eagle@gmail.com` +- **영향**: 3명 사용자 이메일 동기화 실패 (매분 재시도 중) + - happybell80 (goeun2dc@gmail.com) + - 0914eagle (0914eagle@gmail.com) + - cdctfm (cdctfm@gmail.com) + +### Cron 트리거 권한 오류 +- **증상**: `Unauthorized cron trigger attempt` 경고 발생 +- **위치**: rb8001/main.py:558 +- **문제**: 인증 실패에도 요청 처리 계속됨 (보안 취약) + +## 2. 원인 분석 + +### Email 인증 실패 원인 +```python +# skill-email/services/gmail_service.py:49 +if creds_result is None: + return Err(EmailError(f"No credentials found for user: {user_id}")) + +# skill-email/services/db_credentials_provider.py:63 +SELECT token_data->>'refresh_token' as refresh_token +FROM gmail_token # 테이블명 문제: 실제 DB는 gmail_tokens (복수형) +WHERE slack_user_id = %s AND is_equipped = true +``` + +1. **테이블명 불일치**: 코드는 `gmail_token`, DB는 `gmail_tokens` +2. **토큰 데이터 구조**: token_data JSONB 내부에 저장 (250909 문서 확인) +3. **is_equipped 조건**: 토큰이 있어도 장착되지 않으면 조회 실패 + +### Cron 인증 취약점 +```python +# rb8001/main.py:556-560 +expected_token = settings.CRON_TOKEN if hasattr(settings, 'CRON_TOKEN') else "cron-secret-2024" + +if auth_header != f"Bearer {expected_token}": + logger.warning("Unauthorized cron trigger attempt") + # raise HTTPException(status_code=401, detail="Unauthorized") # 주석 처리됨! +``` + +- 하드코딩된 기본 토큰 사용 +- 인증 실패시 경고만 기록, 요청은 계속 처리 + +## 3. 관련 문서 참조 + +- **250909**: gmail_refresh_token 컬럼/JSONB 불일치 해결 +- **250825**: Gmail 토큰 만료 문제 (동일 사용자 3명) +- **250801**: 크론잡 로그 동기화 설정 + +## 4. 해결 방안 + +### 즉시 조치 (로컬 개발자) +```python +# 1. skill-email 테이블명 수정 +# services/db_credentials_provider.py:67 +- FROM gmail_token ++ FROM gmail_tokens # 복수형으로 수정 + +# 2. Cron 인증 강화 +# rb8001/main.py:560 +- # raise HTTPException(status_code=401, detail="Unauthorized") ++ raise HTTPException(status_code=401, detail="Unauthorized") +``` + +### 서버 작업 필요 (서버 관리자) +```sql +-- 토큰 상태 확인 +SELECT slack_user_id, is_equipped, + token_data->>'refresh_token' IS NOT NULL as has_token +FROM gmail_tokens +WHERE slack_user_id IN ('0914eagle', 'happybell80', 'cdctfm'); + +-- is_equipped 설정 +UPDATE gmail_tokens +SET is_equipped = true +WHERE slack_user_id IN ('0914eagle', 'happybell80', 'cdctfm'); +``` + +## 5. 교훈 + +1. **테이블명 일관성**: 단수/복수형 통일 필요 (250911 문서 참조) +2. **보안 우선**: 인증 실패시 반드시 요청 차단 +3. **환경변수 사용**: 하드코딩 대신 .env 파일 활용 +4. **토큰 관리**: JSONB 구조로 일원화 완료, 테이블명만 수정 필요 \ No newline at end of file