docs: Gmail OAuth 404 에러 해결 및 return_url 구현 문서화

- email_sequences.md: Gmail Passport 방식 시퀀스 다이어그램 추가
- authentication_system.md: Gmail Passport 엔드포인트 문서화
- 트러블슈팅: 250901 Gmail OAuth 404 에러 및 return_url 구현 문서 추가
This commit is contained in:
happybell80 2025-09-01 18:27:01 +09:00
parent aa2c15f6d8
commit 1c8ef7fa30
3 changed files with 180 additions and 13 deletions

View File

@ -112,6 +112,25 @@ sequenceDiagram
- redirect_uri: "http://localhost:3000"
- callback_url: "https://auth.ro-being.com/..."
## Gmail Passport 시스템
### 엔드포인트
1. **발급 시작**: `GET /auth/gmail/passport`
- Parameters:
- `user_id`: 사용자 ID (필수)
- `return_url`: OAuth 완료 후 돌아갈 URL (선택)
- Response: Google OAuth 페이지로 302 Redirect
2. **콜백 처리**: `GET /auth/gmail/passport/callback`
- Google OAuth 콜백 자동 처리
- 토큰 저장 후 return_url 또는 /game으로 리다이렉트
- 성공 시: `?gmail=success&email={email}` 파라미터 추가
### 특징
- **원페이지 복귀**: OAuth 인증 후 원래 있던 페이지로 자동 복귀
- **상태 관리**: state 파라미터에 return_url 포함하여 전달
- **토큰 저장**: gmail_tokens 테이블에 암호화 저장
## 보안 고려사항
### 구현된 보안 기능

View File

@ -18,46 +18,50 @@
## 1. Gmail OAuth 인증
### 1.1 최초 Gmail 연결 (프론트엔드 시작)
### 1.1 최초 Gmail 연결 (프론트엔드 시작) - Gmail Passport 방식
```mermaid
sequenceDiagram
participant User as 사용자
participant Front as 프론트엔드
participant Gateway as Gateway(8100)
participant Auth as auth-server(9000)
participant Google as Google OAuth
participant DB as PostgreSQL
User->>Front: Gmail 연결 버튼 클릭
Front->>Gateway: POST /api/auth/gmail/connect
Gateway->>Auth: 인증 요청 전달
Note over Front: 현재 페이지 URL 저장
Front->>Auth: GET /auth/gmail/passport
Note over Auth: ?user_id={userId}<br/>&return_url={currentUrl}
Auth->>Auth: state 토큰 생성
Auth->>DB: state 임시 저장
Auth->>Auth: state 데이터 생성
Note over Auth: {user_id, timestamp,<br/>return_url} → JSON
Auth->>Auth: OAuth URL 생성
Note over Auth: client_id, redirect_uri,<br/>scopes, state 포함
Auth-->>Gateway: OAuth URL 반환
Gateway-->>Front: 리다이렉트 URL
Auth-->>Front: 302 Redirect to Google
Front->>Google: 브라우저 리다이렉트
User->>Google: Google 계정 로그인
User->>Google: 권한 승인
Note over Google: gmail.send<br/>gmail.readonly<br/>gmail.modify
Google->>Auth: 인증 코드 콜백
Note over Auth: /api/auth/gmail/callback
Google->>Auth: GET /auth/gmail/passport/callback
Note over Auth: ?code={auth_code}&state={state}
Auth->>DB: state 검증
Auth->>Auth: state 파싱 및 검증
Note over Auth: user_id, return_url 추출
Auth->>Google: 토큰 교환 요청
Google-->>Auth: access_token, refresh_token
Auth->>DB: gmail_tokens 테이블 저장
Note over DB: user_id, email,<br/>tokens (암호화),<br/>scopes, metadata
Auth-->>Front: 인증 완료 리다이렉트
Front->>Front: 성공 메시지 표시
Auth->>Auth: 리다이렉트 URL 결정
Note over Auth: return_url 있으면 해당 페이지<br/>없으면 /game 기본값
Auth-->>Front: 302 Redirect
Note over Front: {return_url}?gmail=success<br/>&email={email}
Front->>Front: 원래 페이지에서 성공 메시지 표시
```
### 1.2 Slack에서 Gmail 연결

View File

@ -0,0 +1,144 @@
# Gmail OAuth 404 에러 및 Return URL 구현
## 작성일: 2025-09-01
## 작성자: happybell80
## 관련 서비스: auth-server, frontend-customer
---
## 18시 30분 - 문제 발견
### 문제 상황
1. **Frontend 404 오류**
- Gmail OAuth 성공 후 `/settings/items` 페이지로 리다이렉트
- 해당 라우트가 Frontend에 존재하지 않아 404 에러 발생
- 실제 아이템 관리 페이지는 `/inventory`
2. **UX 문제**
- OAuth 인증 후 `/inventory` 페이지로 이동
- 사용자가 원래 있던 페이지로 돌아가려면 수동 이동 필요
### 원인 분석
```typescript
// frontend-customer/src/App.tsx
<Route path="/inventory" component={InventoryPage} /> // 존재
<Route path="/settings/items" ... /> // 존재하지 않음
// auth-server/app/providers/gmail_passport.py:223
return RedirectResponse(f"https://ro-being.com/settings/items?gmail=success&email={email}")
// 잘못된 경로로 리다이렉트
```
---
## 18시 45분 - 1차 수정: 404 에러 해결
### 수정 내용
```python
# auth-server/app/providers/gmail_passport.py:223
# 변경 전
return RedirectResponse(f"https://ro-being.com/settings/items?gmail=success&email={email}")
# 변경 후
return RedirectResponse(f"https://ro-being.com/inventory?gmail=success&email={email}")
```
### 결과
- 404 에러 해결 ✅
- `/inventory` 페이지로 정상 리다이렉트
- 하지만 여전히 원래 페이지로 돌아가지 못함
---
## 19시 00분 - 2차 수정: Return URL 구현
### 구현 전략
1. OAuth 요청 시 현재 페이지 URL을 `return_url` 파라미터로 전달
2. auth-server에서 state에 return_url 저장
3. OAuth 콜백 처리 시 return_url로 리다이렉트
4. return_url이 없으면 기본값 `/game` 사용
### 수정 내용
#### 1. Frontend - OAuth 요청에 return_url 추가
```typescript
// frontend-customer/src/components/skills-items-panel.tsx:359-364
// 변경 전
const authUrl = `https://auth.ro-being.com/auth/gmail/passport?user_id=${userId}`;
sessionStorage.setItem('gmail_oauth_return_url', window.location.href);
window.location.href = authUrl;
// 변경 후
const currentUrl = window.location.href;
const authUrl = `https://auth.ro-being.com/auth/gmail/passport?user_id=${userId}&return_url=${encodeURIComponent(currentUrl)}`;
window.location.href = authUrl;
```
#### 2. auth-server - return_url 처리 추가
```python
# app/providers/gmail_passport.py
# 1) 발급 엔드포인트 수정 (line 58)
@router.get("/")
async def issue_passport(user_id: str = Query(...), return_url: str = Query(default=None)):
# state에 return_url 포함
state_data = {"user_id": user_id, "timestamp": time.time()}
if return_url:
state_data["return_url"] = return_url
state = json.dumps(state_data)
# 2) 콜백 처리 수정 (line 225-235)
# return_url이 있으면 해당 페이지로, 없으면 기본 페이지로
return_url = state_data.get("return_url")
if return_url:
separator = "&" if "?" in return_url else "?"
redirect_url = f"{return_url}{separator}gmail=success&email={email}"
else:
redirect_url = f"https://ro-being.com/game?gmail=success&email={email}"
return RedirectResponse(redirect_url)
```
---
## 19시 15분 - 배포 및 검증
### Git 커밋
```bash
# auth-server
git commit -m "feat: OAuth 인증 후 이전 페이지로 자동 복귀 구현"
# frontend-customer
git commit -m "feat: Gmail OAuth 요청 시 return_url 파라미터 추가"
```
### 테스트 시나리오
1. `/game` 페이지에서 Gmail 연결 → OAuth 완료 → `/game` 복귀 ✅
2. `/game001` 페이지에서 Gmail 연결 → OAuth 완료 → `/game001` 복귀 ✅
3. return_url 없이 직접 접근 → OAuth 완료 → `/game` (기본값) ✅
---
## 교훈
### 개발 원칙
1. **라우트 변경 시 양쪽 확인**: Frontend 라우트 변경 시 Backend 리다이렉트 경로도 함께 확인
2. **UX 우선**: OAuth 같은 외부 플로우는 원래 페이지로 복귀가 기본
3. **파라미터 전달**: state 파라미터를 활용한 컨텍스트 유지
### 기술적 포인트
1. **URL 인코딩**: return_url은 반드시 `encodeURIComponent()` 처리
2. **쿼리 파라미터 처리**: 기존 쿼리 있는 URL에 파라미터 추가 시 `?` vs `&` 구분
3. **기본값 설정**: return_url 없을 때 합리적인 기본값 제공
### 문서 업데이트
- `300_architecture/sequences/email_sequences.md`: Gmail Passport 플로우 추가
- `300_architecture/380_authentication_system.md`: Gmail Passport 엔드포인트 문서화
---
## 참고 자료
- 관련 PR: auth-server #fc94303, frontend-customer #26e7f70
- 영향받는 파일:
- auth-server/app/providers/gmail_passport.py
- frontend-customer/src/components/skills-items-panel.tsx