d4fd4a67e2
@capacitor-community/apple-sign-in 으로 identityToken 획득 → /api/auth/apple. 애플 버튼은 네이티브 iOS 에서만 노출, 시트 취소는 무시. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
36 lines
1.6 KiB
TypeScript
36 lines
1.6 KiB
TypeScript
// Sign in with Apple — 네이티브(iOS) 전용 래퍼.
|
|
// @capacitor-community/apple-sign-in 플러그인으로 identityToken(JWT)을 받아온다.
|
|
// 이 토큰의 aud 는 앱 번들 ID(=capacitor appId)이며, 백엔드가 APPLE_CLIENT_ID 로 검증한다.
|
|
import { Capacitor } from '@capacitor/core'
|
|
import { SignInWithApple } from '@capacitor-community/apple-sign-in'
|
|
|
|
// capacitor.config 의 appId 와 일치. iOS 네이티브 플로우의 aud 가 된다.
|
|
const APPLE_CLIENT_ID = 'kr.sblog.dognation'
|
|
|
|
export interface AppleCredential {
|
|
identityToken: string
|
|
/** 애플은 최초 인증 시에만 이름을 준다. 이후에는 null. */
|
|
name: string | null
|
|
}
|
|
|
|
/** 현재 실행 환경이 네이티브(iOS)인지 — 애플 로그인 지원 여부. */
|
|
export function isAppleSignInAvailable(): boolean {
|
|
return Capacitor.isNativePlatform() && Capacitor.getPlatform() === 'ios'
|
|
}
|
|
|
|
/**
|
|
* 네이티브 Sign in with Apple 을 실행하고 identityToken 을 반환한다.
|
|
* 사용자가 취소하면 플러그인이 reject 하므로 호출부에서 구분 처리한다.
|
|
*/
|
|
export async function signInWithApple(): Promise<AppleCredential> {
|
|
const { response } = await SignInWithApple.authorize({
|
|
clientId: APPLE_CLIENT_ID,
|
|
// iOS 네이티브 플로우에서는 사용되지 않지만 타입상 필요.
|
|
redirectURI: `https://${APPLE_CLIENT_ID}/apple/callback`,
|
|
scopes: 'name email',
|
|
})
|
|
// familyName + givenName (한국식). 최초 인증에만 제공되며, 없으면 null.
|
|
const name =
|
|
[response.familyName, response.givenName].filter(Boolean).join(' ').trim() || null
|
|
return { identityToken: response.identityToken, name }
|
|
} |