From b4ff55d55af1c6f1adbdb71d5ae79929d08aed70 Mon Sep 17 00:00:00 2001 From: Stephen Zhou <38493346+hyoban@users.noreply.github.com> Date: Fri, 20 Dec 2024 21:27:43 +0800 Subject: [PATCH] fix: sign In with Apple With ID Token not work (#966) --- docs/content/docs/authentication/apple.mdx | 4 ++++ packages/better-auth/src/social-providers/apple.ts | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/content/docs/authentication/apple.mdx b/docs/content/docs/authentication/apple.mdx index 9d192ba65a..0ca9b6baaa 100644 --- a/docs/content/docs/authentication/apple.mdx +++ b/docs/content/docs/authentication/apple.mdx @@ -25,10 +25,14 @@ description: Apple provider setup and usage. apple: { // [!code highlight] clientId: process.env.APPLE_CLIENT_ID as string, // [!code highlight] clientSecret: process.env.APPLE_CLIENT_SECRET as string, // [!code highlight] + // Optional + appBundleIdentifier: process.env.APPLE_APP_BUNDLE_IDENTIFIER as string, // [!code highlight] }, // [!code highlight] }, }) ``` + + On native iOS, it doesn't use the service id but the app id (bundle id) as client id, so if using the service id as clientId in signIn.social() with idToken, it throws an error: JWTClaimValidationFailed: unexpected "aud" claim value. So you need to provide the appBundleIdentifier when you want to sign in with Apple using the ID Token. diff --git a/packages/better-auth/src/social-providers/apple.ts b/packages/better-auth/src/social-providers/apple.ts index 41cbc1b9a8..93b291db64 100644 --- a/packages/better-auth/src/social-providers/apple.ts +++ b/packages/better-auth/src/social-providers/apple.ts @@ -64,7 +64,9 @@ export interface AppleNonConformUser { email: string; } -export interface AppleOptions extends ProviderOptions {} +export interface AppleOptions extends ProviderOptions { + appBundleIdentifier?: string; +} export const apple = (options: AppleOptions) => { const tokenEndpoint = "https://appleid.apple.com/auth/token"; @@ -105,7 +107,7 @@ export const apple = (options: AppleOptions) => { const { payload: jwtClaims } = await jwtVerify(token, publicKey, { algorithms: [jwtAlg], issuer: "https://appleid.apple.com", - audience: options.clientId, + audience: options.appBundleIdentifier || options.clientId, maxTokenAge: "1h", }); ["email_verified", "is_private_email"].forEach((field) => { @@ -125,7 +127,7 @@ export const apple = (options: AppleOptions) => { if (!token.idToken) { return null; } - const profile = decodeJwt(token.idToken)?.payload as AppleProfile | null; + const profile = decodeJwt(token.idToken); if (!profile) { return null; }