85 lines
4.8 KiB
Markdown
85 lines
4.8 KiB
Markdown
# Headless 전화번호 인증 로그인 로직
|
|
|
|
이 문서는 사용자가 데모 애플리케이션에서 **전화번호**를 입력하여 인증 링크를 받고, 모바일에서 승인하여 로그인하는 내부 흐름을 설명합니다.
|
|
|
|
## 핵심 개념
|
|
|
|
- **Link Init**: 사용자의 전화번호로 실제 인증 링크(카카오톡 또는 SMS)를 발송하도록 SSO 서버에 요청하는 단계입니다.
|
|
- **Polling**: 사용자가 모바일에서 링크를 클릭할 때까지 앱 서버가 주기적으로 SSO 서버에 "인증이 완료되었는지" 물어보는 과정입니다.
|
|
- **Security**: 이 과정에서도 모든 API 호출은 RP의 Private Key로 서명된 `client_assertion`을 포함하여 보안을 유지합니다.
|
|
|
|
---
|
|
|
|
## 1. 전화번호 로그인 시퀀스 다이어그램
|
|
|
|
```mermaid
|
|
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 서버에 알려주는 매개체가 됩니다.
|
|
|
|
### [2단계] 링크 발송 요청 (Link Init)
|
|
- **동작**: `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초)으로 제한되며, 이후에는 요청을 처음부터 다시 시작해야 합니다.
|