1
0
forked from baron/baron-sso
Files
baron-sso/ISSUE.md

55 lines
3.7 KiB
Markdown

# 비밀번호 재설정 로직 분석 및 이슈 리포트
## 1. 전체 프로세스 흐름 (수정 후)
이메일 보안 스캐너(Link Scanner)로 인한 토큰 조기 만료 문제를 방지하기 위해 **"중간 페이지(Interstitial Page)"** 방식이 적용되었습니다.
1. **초기화 요청 (Frontend -> Backend)**
* 사용자가 아이디를 입력하고 비밀번호 재설정을 요청합니다.
* Backend는 Descope API를 호출하여 이메일을 발송합니다.
* 이때 리다이렉트 URL은 백엔드 API (`/api/v1/auth/password/reset/verify`)로 설정됩니다.
2. **이메일 수신 및 클릭 (User)**
* 사용자가 이메일 내의 링크를 클릭합니다.
* URL 예시: `https://sso.hmac.kr/api/v1/auth/password/reset/verify?t=<TOKEN>`
3. **검증 대기 페이지 (Backend GET 처리)**
* **보안 스캐너 방어:** 백엔드가 GET 요청을 받으면 즉시 토큰을 검증하지 않습니다.
* 대신, 사용자가 직접 버튼을 클릭해야 하는 **HTML 페이지(폼)**를 반환합니다.
* **이유:** Outlook, Gmail 등의 이메일 서버가 링크의 안전성을 확인하기 위해 미리 방문(GET)하여 일회성 토큰을 소모해버리는 것을 방지하기 위함입니다.
4. **검증 실행 (User Click -> Backend POST)**
* 사용자가 HTML 페이지의 "계속하기" 버튼을 클릭합니다.
* `POST` 요청이 백엔드로 전송됩니다.
* 백엔드는 이때 Descope를 통해 토큰을 검증하고, 성공 시 **리프레시 토큰 쿠키(DSRF)**를 브라우저에 설정합니다.
* 이후 프론트엔드 페이지(`https://sso.hmac.kr/reset-password?loginId=...`)로 리다이렉트합니다.
5. **비밀번호 변경 (Frontend -> Backend)**
* 프론트엔드는 URL 파라미터의 `loginId`와 사용자가 입력한 `새 비밀번호`를 가지고 백엔드에 요청을 보냅니다.
* 이때 4번 단계에서 설정된 **쿠키**가 함께 전송되어 인증된 상태로 비밀번호가 변경됩니다.
---
## 2. 주요 사용 함수 (`backend/internal/handler/auth_handler.go`)
| 함수명 | HTTP Method | 역할 |
| :--- | :--- | :--- |
| **`InitiatePasswordReset`** | `POST` | Descope에 비밀번호 재설정 이메일 발송을 요청하고 리다이렉트 URL을 백엔드로 지정합니다. |
| **`VerifyPasswordResetPage`** | `GET` | 토큰 검증 없이 사용자의 클릭을 유도하는 **HTML 중간 페이지**를 렌더링합니다. |
| **`ProcessPasswordResetToken`** | `POST` | 실제 Descope 토큰 검증을 수행하고 세션 쿠키를 생성한 뒤 프론트엔드로 이동시킵니다. |
| **`CompletePasswordReset`** | `POST` | 최종적으로 새 비밀번호를 업데이트합니다. (쿠키 기반 인증 필요) |
---
## 3. 비밀번호 변경이 안 되었던 원인
### 1) 토큰 조기 소모 (Token Expired / Invalid)
* **증상:** 사용자가 링크를 클릭하자마자 "Invalid or expired token" 오류 발생.
* **원인:** 회사 이메일 보안 시스템이 링크의 안전성을 검사하기 위해 사용자가 클릭하기 전 미리 방문(GET 요청)했습니다. Descope 토큰은 **일회용**이므로 스캐너 방문 시 이미 소모되어, 정작 사용자가 방문했을 때는 만료된 상태가 되었습니다.
* **해결:** `GET`은 페이지 로드만 수행하고, 사용자의 클릭(`POST`) 시에만 검증하도록 로직을 분리했습니다.
### 2) 파라미터 이름 불일치
* **증상:** `missing_token` 오류 발생.
* **원인:** 백엔드는 `token` 파라미터를 찾았으나, Descope는 `t`라는 이름으로 토큰을 전달했습니다.
* **해결:** `token``t` 두 파라미터를 모두 확인하도록 수정했습니다.