docs: Gmail 토큰 NULL 문제를 토큰 만료 문제로 정정

- token_data=NULL이 아니라 access_token 만료가 실제 문제
- 신규 컬럼(access_token, refresh_token) 사용 중
- 파일명 변경: gmail_token_null → gmail_token_expired
- 문서 내용 수정:
  - token_data NULL 언급 제거
  - access_token 만료 문제로 수정
  - 갱신 API 사용법 추가

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
happybell80 2025-08-28 01:45:25 +09:00
parent 63f774e71f
commit a141599bf0

View File

@ -1,4 +1,4 @@
# Gmail 토큰 NULL 및 대화 저장 실패 문제 해결 가이드 # Gmail 토큰 만료 및 대화 저장 실패 문제 해결 가이드
## 작성일: 2025-08-25 ## 작성일: 2025-08-25
## 작성자: 서버 관리자 ## 작성자: 서버 관리자
@ -21,17 +21,18 @@
### 1.2 근본 원인 ### 1.2 근본 원인
```sql ```sql
-- 현재 DB 상태: 모든 사용자 token_data가 NULL -- 현재 DB 상태: 모든 사용자 토큰 만료
SELECT username, has_token, is_equipped SELECT username, access_token IS NOT NULL as has_token,
expires_at < extract(epoch from now()) as is_expired
FROM gmail_tokens; FROM gmail_tokens;
결과: 결과:
happybell80 | f (NULL) | t (장착됨) -- 모순 상태 happybell80 | t (있음) | t (만료됨)
0914eagle | f (NULL) | t (장착됨) -- 모순 상태 0914eagle | t (있음) | t (만료됨)
cdctfm | f (NULL) | t (장착됨) -- 모순 상태 cdctfm | t (있음) | t (만료됨)
``` ```
**문제**: is_equipped=true이지만 실제 token_data=NULL **문제**: access_token은 있지만 만료되어 사용 불가
--- ---
@ -49,7 +50,7 @@ sequenceDiagram
Cron->>RB: POST /api/cron/daily-summary Cron->>RB: POST /api/cron/daily-summary
RB->>Email: GET /messages?user_id={slack_id} RB->>Email: GET /messages?user_id={slack_id}
Email->>DB: SELECT token_data FROM gmail_tokens Email->>DB: SELECT token_data FROM gmail_tokens
DB-->>Email: token_data: NULL DB-->>Email: access_token: expired
Email-->>RB: 500 Internal Server Error Email-->>RB: 500 Internal Server Error
RB->>Slack: 불완전한 브리핑 전송<br/>(이메일 없이 뉴스만) RB->>Slack: 불완전한 브리핑 전송<br/>(이메일 없이 뉴스만)
``` ```
@ -72,7 +73,7 @@ sequenceDiagram
Google->>Auth: Callback with code Google->>Auth: Callback with code
Auth->>Google: Exchange code for tokens Auth->>Google: Exchange code for tokens
Google-->>Auth: access_token, refresh_token Google-->>Auth: access_token, refresh_token
Auth->>DB: UPDATE gmail_tokens<br/>SET token_data = {...} Auth->>DB: UPDATE gmail_tokens<br/>SET access_token, refresh_token
Auth-->>Front: 인증 완료 Auth-->>Front: 인증 완료
``` ```
@ -80,9 +81,12 @@ sequenceDiagram
## 3. 해결 방안 ## 3. 해결 방안
### 3.1 해결책 - 관리자 대신 인증 ### 3.1 해결책 - 토큰 갱신 또는 재인증
```bash ```bash
# 1. 테스트 계정으로 OAuth 인증 URL 생성 # 1. 토큰 갱신 (만료된 경우)
curl -X POST "http://localhost:9000/api/gmail/refresh/1e16e9d5-59f3-54da-a661-8abeabff4230"
# 2. 갱신 실패 시 OAuth 재인증 URL 생성
curl -X GET "http://localhost:9000/api/gmail/auth?user_id=1e16e9d5-59f3-54da-a661-8abeabff4230" curl -X GET "http://localhost:9000/api/gmail/auth?user_id=1e16e9d5-59f3-54da-a661-8abeabff4230"
# 2. 반환된 URL을 브라우저에서 열어 Google 로그인 # 2. 반환된 URL을 브라우저에서 열어 Google 로그인
@ -91,7 +95,7 @@ curl -X GET "http://localhost:9000/api/gmail/auth?user_id=1e16e9d5-59f3-54da-a66
# 4. 토큰 저장 확인 # 4. 토큰 저장 확인
export PGPASSWORD=robeings export PGPASSWORD=robeings
psql -h localhost -U robeings -d main_db -c \ psql -h localhost -U robeings -d main_db -c \
"SELECT user_id, token_data IS NOT NULL FROM gmail_tokens WHERE user_id = '1e16e9d5-59f3-54da-a661-8abeabff4230';" "SELECT user_id, access_token IS NOT NULL FROM gmail_tokens WHERE user_id = '1e16e9d5-59f3-54da-a661-8abeabff4230';"
# 5. 브리핑 수동 테스트 # 5. 브리핑 수동 테스트
curl -X POST http://192.168.219.52:8001/api/cron/daily-summary \ curl -X POST http://192.168.219.52:8001/api/cron/daily-summary \
@ -115,16 +119,20 @@ curl -X POST http://192.168.219.52:8001/api/cron/daily-summary \
# 1. 토큰 상태 확인 # 1. 토큰 상태 확인
export PGPASSWORD=robeings export PGPASSWORD=robeings
psql -h localhost -U robeings -d main_db -c \ psql -h localhost -U robeings -d main_db -c \
"SELECT u.username, gt.token_data IS NOT NULL as has_token, "SELECT u.username, gt.access_token IS NOT NULL as has_token,
gt.is_equipped, gt.metadata->>'email' as email gt.expires_at < extract(epoch from now()) as is_expired,
gt.metadata->>'email' as email
FROM users u FROM users u
LEFT JOIN gmail_tokens gt ON u.id = gt.user_id LEFT JOIN gmail_tokens gt ON u.id = gt.user_id
WHERE u.username IN ('happybell80', '0914eagle', 'cdctfm');" WHERE u.username IN ('happybell80', '0914eagle', 'cdctfm');"
``` ```
### Step 2: 테스트 계정 인증 (15분) ### Step 2: 토큰 갱신 또는 재인증 (15분)
```bash ```bash
# 1. OAuth URL 생성 (happybell80 계정) # 1. 토큰 갱신 시도 (happybell80 계정)
curl -X POST "http://localhost:9000/api/gmail/refresh/1e16e9d5-59f3-54da-a661-8abeabff4230"
# 2. 갱신 실패 시 OAuth URL 생성
curl -s "http://localhost:9000/api/gmail/auth?user_id=1e16e9d5-59f3-54da-a661-8abeabff4230" | jq -r '.auth_url' curl -s "http://localhost:9000/api/gmail/auth?user_id=1e16e9d5-59f3-54da-a661-8abeabff4230" | jq -r '.auth_url'
# 2. 브라우저에서 URL 열고 Google 계정으로 로그인 # 2. 브라우저에서 URL 열고 Google 계정으로 로그인
@ -132,7 +140,7 @@ curl -s "http://localhost:9000/api/gmail/auth?user_id=1e16e9d5-59f3-54da-a661-8a
# 4. 인증 성공 확인 # 4. 인증 성공 확인
psql -h localhost -U robeings -d main_db -c \ psql -h localhost -U robeings -d main_db -c \
"SELECT token_data->'access_token' IS NOT NULL as success "SELECT access_token IS NOT NULL as success
FROM gmail_tokens FROM gmail_tokens
WHERE user_id = '1e16e9d5-59f3-54da-a661-8abeabff4230';" WHERE user_id = '1e16e9d5-59f3-54da-a661-8abeabff4230';"
``` ```
@ -164,7 +172,7 @@ curl -s "http://localhost:9000/api/gmail/auth?user_id=69ae4ea9-a15f-5110-9f5d-65
## 5. 검증 체크리스트 ## 5. 검증 체크리스트
- [ ] 모든 사용자의 token_data NOT NULL 확인 - [ ] 모든 사용자의 access_token 유효성 확인
- [ ] 수동 브리핑 실행 시 이메일 포함 확인 - [ ] 수동 브리핑 실행 시 이메일 포함 확인
- [ ] Slack DM으로 완전한 브리핑 수신 확인 - [ ] Slack DM으로 완전한 브리핑 수신 확인
@ -221,5 +229,5 @@ DATABASE_URL=postgresql://robeings:robeings@192.168.219.45:5432/main_db
## 예상 소요 시간: 1시간 30분 ## 예상 소요 시간: 1시간 30분
- Gmail 토큰 문제: 1시간 - Gmail 토큰 갱신: 10분
- ~~State Service DB 설정~~: 필요 없음 (직접 DB 연결) - ~~State Service DB 설정~~: 필요 없음 (직접 DB 연결)