Files
headless-login-demo/docs/headless-phone-login-flow.md
2026-04-13 15:20:54 +09:00

4.8 KiB

Headless 전화번호 인증 로그인 로직

이 문서는 사용자가 데모 애플리케이션에서 전화번호를 입력하여 인증 링크를 받고, 모바일에서 승인하여 로그인하는 내부 흐름을 설명합니다.

핵심 개념

  • Link Init: 사용자의 전화번호로 실제 인증 링크(카카오톡 또는 SMS)를 발송하도록 SSO 서버에 요청하는 단계입니다.
  • Polling: 사용자가 모바일에서 링크를 클릭할 때까지 앱 서버가 주기적으로 SSO 서버에 "인증이 완료되었는지" 물어보는 과정입니다.
  • Security: 이 과정에서도 모든 API 호출은 RP의 Private Key로 서명된 client_assertion을 포함하여 보안을 유지합니다.

1. 전화번호 로그인 시퀀스 다이어그램

sequenceDiagram
    autonumber
    actor User as 사용자
    participant RP as 데모 앱 (RP)
    participant OIDC as Baron SSO (OIDC)
    participant Auth as Baron SSO (Headless API)

    User->>RP: 1. 전화번호 입력 후 인증 요청
    
    note over RP: [1단계: 신호 요청]
    RP->>OIDC: 2. Authorization Request (GET /oauth2/auth)<br/>[login_challenge 획득]
    
    note over RP: [2단계: 링크 발송 요청]
    RP->>Auth: 3. 인증 링크 발송 요청 (POST .../link/init)<br/>[client_assertion, login_challenge, 전화번호 포함]
    Auth-->>User: 4. 인증 링크 발송 (카카오톡/SMS)
    Auth-->>RP: 5. 대기 참조값(pendingRef) 반환
    
    note over RP: [3단계: 인증 상태 폴링]
    loop 인증 완료 시까지 반복 (최대 3분)
        RP->>Auth: 6. 상태 확인 (POST .../link/poll)<br/>[client_assertion, pendingRef 포함]
        alt 아직 대기 중
            Auth-->>RP: 7. authorization_pending 응답
            RP->>RP: 잠시 대기 (interval)
        else 사용자 링크 클릭 완료
            Auth-->>RP: 8. 인증 성공 및 리다이렉트 URL 반환
        end
    end
    
    note over User: 사용자가 모바일에서 링크 클릭 및 승인
    
    note over RP: [4단계: 이후 과정 (사번 로그인과 동일)]
    RP->>OIDC: 9. 리다이렉트 추적 및 Authorization Code 획득
    RP->>OIDC: 10. Token Endpoint 호출 및 id_token 발급
    RP->>RP: 11. 세션 생성 및 홈 화면 이동
    RP-->>User: 12. 로그인 완료 안내

2. 단계별 상세 로직 설명

[1단계] 신호 요청 (Login Challenge)

  • 사번 로그인과 동일하게 OIDC 표준 흐름을 시작하기 위해 login_challenge를 먼저 획득합니다. 이 값은 이후 인증 시도 시 "이 사용자가 어떤 OIDC 요청에 응답하고 있는지"를 SSO 서버에 알려주는 매개체가 됩니다.
  • 동작: POST /api/v1/auth/headless/link/init 호출.
  • 데이터: client_assertion, login_challenge, 사용자의 loginId(전화번호).
  • 결과: SSO 서버는 사용자의 전화번호로 인증 가능한 고유 링크를 발송하고, RP에게는 해당 요청을 추적할 수 있는 pendingRef와 다음 폴링까지의 권장 대기 시간(interval)을 반환합니다.

[3단계] 인증 상태 폴링 (Polling)

  • 동작: POST /api/v1/auth/headless/link/poll을 주기적으로 호출.
  • 상태 처리:
    • authorization_pending: 사용자가 아직 링크를 클릭하지 않았으므로 지정된 시간만큼 기다린 후 다시 시도합니다.
    • slow_down: 폴링 간격이 너무 잦다는 신호로, 대기 시간을 조금 더 늘립니다.
    • expired_token: 3분이 경과하여 인증 요청이 만료된 경우입니다.
    • 성공: 사용자가 승인을 완료하면 서버는 redirectTo 정보를 반환하며 폴링이 종료됩니다.

[4단계] 이후 과정 (Standard OIDC Flow)

  • 폴링 결과로 받은 redirectTo 주소부터는 표준 OIDC 흐름을 따릅니다.
  • 데모 앱은 해당 주소로 리다이렉트하며 발생하는 쿠키를 유지하고, 필요 시 사용자 동의(Consent) 과정을 자동 수행하여 최종적으로 Authorization Code를 얻어냅니다.
  • 마지막으로 해당 코드를 id_token으로 교환하여 사용자 정보를 세션에 저장합니다.

3. 특징 및 주의 사항

  • 비동기 사용자 경험: 사용자는 PC에서 전화번호만 입력하고, 실제 인증 행위는 모바일에서 수행합니다. PC 화면은 폴링이 완료될 때까지 "인증 대기 중" 상태를 유지합니다.
  • 보안 검증: 폴링 시에도 client_assertion이 필요합니다. 이는 제3자가 pendingRef를 가로채더라도 RP의 비밀키 없이는 인증 상태를 훔쳐볼 수 없음을 보장합니다.
  • 제한 시간: 보안상 폴링은 보통 3분(180초)으로 제한되며, 이후에는 요청을 처음부터 다시 시작해야 합니다.