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

3.7 KiB

비밀번호 재설정 로직 분석 및 이슈 리포트

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라는 이름으로 토큰을 전달했습니다.
  • 해결: tokent 두 파라미터를 모두 확인하도록 수정했습니다.