POST /api/v1/auth/apple/token
의도
Apple Identity Token(RS256 JWT)으로 dartbrief JWT를 발급한다. 첫 로그인이면 자동으로 계정 생성.
인증
없음 (로그인 전 호출)
입력
json
{
"identity_token": "<Apple Identity Token>",
"raw_nonce": "<랜덤 문자열 원본>"
}두 필드 모두 필수. 하나라도 빈 문자열이면 400 반환.
응답
200 OK
json
{ "token": "eyJhbGci..." }400 Bad Request — identity_token 또는 raw_nonce 누락
401 Unauthorized — Apple 토큰 검증 실패
curl 예제
bash
curl -s -X POST https://api.dartbrief.com/api/v1/auth/apple/token \
-H "Content-Type: application/json" \
-d '{"identity_token":"<Apple ID Token>","raw_nonce":"<rawNonce>"}' | jq
# 로컬
curl -s -X POST http://localhost:8000/api/v1/auth/apple/token \
-H "Content-Type: application/json" \
-d '{"identity_token":"<Apple ID Token>","raw_nonce":"<rawNonce>"}' | jqNonce 플로우
Replay 공격 방지를 위해 nonce를 필수로 사용한다.
Flutter 앱:
1. rawNonce = 32자 무작위 문자열 (Random.secure())
2. hashedNonce = sha256(rawNonce)
3. SignInWithApple.getAppleIDCredential(nonce: hashedNonce)
→ Apple이 identity_token의 nonce claim에 hashedNonce를 삽입
4. POST { identity_token, raw_nonce: rawNonce }
백엔드:
5. sha256(rawNonce) == token.nonce claim 일치 여부 검증
6. 불일치 시 401 반환비즈니스 메모
- Apple Identity Token 유효기간 약 10분 — nonce 없으면 이 시간 안에 replay 가능
- 백엔드가 Apple JWKS (
https://appleid.apple.com/auth/keys, 6h 캐시)로 RS256 서명 검증 audclaim이APPLE_ALLOWED_CLIENT_IDS목록 중 하나와 일치해야 함- dev:
com.dartbrief.app.dev - prod:
com.dartbrief.app
- dev:
oauth_provider = 'APPLE',oauth_id = subclaim 으로 users 테이블 upsert- iOS 전용 — Android에서는 Apple 로그인 버튼 미노출 (
defaultTargetPlatform == TargetPlatform.iOS) - Apple은 최초 로그인 시에만 email/fullName 반환 — 서버에 저장하지 않음 (oauth_id만 사용)