[PR #8870] fix: accept hashed nonces for native iOS sign-in with Apple #16512

Open
opened 2026-04-13 10:33:04 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/8870
Author: @jsj
Created: 4/1/2026
Status: 🔄 Open

Base: mainHead: fix-apple-native-nonce


📝 Commits (3)

  • e0115cf fix(apple): accept hashed nonces for native iOS Sign In
  • cdc5596 chore: add changeset for apple nonce fix
  • 7765348 Merge branch 'main' into fix-apple-native-nonce

📊 Changes

3 files changed (+123 additions, -1 deletions)

View changed files

.changeset/fix-apple-native-nonce.md (+5 -0)
packages/core/src/social-providers/apple.test.ts (+99 -0)
📝 packages/core/src/social-providers/apple.ts (+19 -1)

📄 Description

Summary

Native iOS Sign in with Apple (via Expo's expo-apple-authentication, SwiftUI's SignInWithAppleButton, etc.) requires the client to SHA-256 hash the nonce before setting it on ASAuthorizationAppleIDRequest.nonce. Apple then returns that hashed value in the ID token's nonce claim. The client sends the raw nonce to the backend.

Better Auth's verifyIdToken compares the JWT nonce directly to the raw nonce from the request, so valid native Apple tokens are rejected with INVALID_TOKEN.

This patch falls back to comparing sha256(rawNonce) before rejecting, which fixes native iOS flows while preserving existing web OAuth behaviour.

Who hits this? Any app using Apple's native ASAuthorizationAppleIDProvider — this includes Expo (expo-apple-authentication), SwiftUI (SignInWithAppleButton), and UIKit (ASAuthorizationController) clients. The web OAuth redirect flow is unaffected because it uses the raw nonce throughout.

Changes

  • packages/core/src/social-providers/apple.ts — add sha256Hex + nonceMatches helpers; use them in verifyIdToken
  • packages/core/src/social-providers/apple.test.ts — regression tests: raw match passes, hashed match passes, mismatch rejects

Validation

  • vitest run src/social-providers/apple.test.ts — all pass
  • @better-auth/core typecheck — clean
  • biome check on modified files — clean
  • Fixes #7550 — native Apple sign-in "Invalid id token" where config is correct but nonce verification fails
  • Relates to #8011 — improved error handling for verifyIdToken, but did not address the nonce hash mismatch

Summary by cubic

Accept SHA-256 hashed nonces in Apple ID tokens to support native iOS Sign In with Apple (Expo, SwiftUI, expo-apple-authentication). Prevents rejecting valid native tokens; web OAuth unchanged.

  • Bug Fixes

    • In verifyIdToken, accept raw nonce or sha256(raw) via new sha256Hex and nonceMatches; added tests for raw, hashed, and mismatch cases. Fixes #7550.
  • Dependencies

    • Changeset for @better-auth/core patch release.

Written for commit 7765348aca. Summary will update on new commits.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/8870 **Author:** [@jsj](https://github.com/jsj) **Created:** 4/1/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `fix-apple-native-nonce` --- ### 📝 Commits (3) - [`e0115cf`](https://github.com/better-auth/better-auth/commit/e0115cf600d6ad11d68ace6872804e8992d60842) fix(apple): accept hashed nonces for native iOS Sign In - [`cdc5596`](https://github.com/better-auth/better-auth/commit/cdc559606ca5d5ac0d797521497d4546f9f4d302) chore: add changeset for apple nonce fix - [`7765348`](https://github.com/better-auth/better-auth/commit/7765348acac0817a128ba586dfe2def367483aaf) Merge branch 'main' into fix-apple-native-nonce ### 📊 Changes **3 files changed** (+123 additions, -1 deletions) <details> <summary>View changed files</summary> ➕ `.changeset/fix-apple-native-nonce.md` (+5 -0) ➕ `packages/core/src/social-providers/apple.test.ts` (+99 -0) 📝 `packages/core/src/social-providers/apple.ts` (+19 -1) </details> ### 📄 Description ## Summary Native iOS Sign in with Apple (via Expo's `expo-apple-authentication`, SwiftUI's `SignInWithAppleButton`, etc.) requires the client to SHA-256 hash the nonce before setting it on `ASAuthorizationAppleIDRequest.nonce`. Apple then returns that hashed value in the ID token's `nonce` claim. The client sends the **raw** nonce to the backend. Better Auth's `verifyIdToken` compares the JWT nonce directly to the raw nonce from the request, so valid native Apple tokens are rejected with `INVALID_TOKEN`. This patch falls back to comparing `sha256(rawNonce)` before rejecting, which fixes native iOS flows while preserving existing web OAuth behaviour. > **Who hits this?** Any app using Apple's native `ASAuthorizationAppleIDProvider` — this includes Expo (`expo-apple-authentication`), SwiftUI (`SignInWithAppleButton`), and UIKit (`ASAuthorizationController`) clients. The web OAuth redirect flow is unaffected because it uses the raw nonce throughout. ## Changes - `packages/core/src/social-providers/apple.ts` — add `sha256Hex` + `nonceMatches` helpers; use them in `verifyIdToken` - `packages/core/src/social-providers/apple.test.ts` — regression tests: raw match passes, hashed match passes, mismatch rejects ## Validation - `vitest run src/social-providers/apple.test.ts` — all pass - `@better-auth/core` typecheck — clean - `biome check` on modified files — clean ## Related issues - Fixes #7550 — native Apple sign-in "Invalid id token" where config is correct but nonce verification fails - Relates to #8011 — improved error handling for `verifyIdToken`, but did not address the nonce hash mismatch <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Accept SHA-256 hashed nonces in Apple ID tokens to support native iOS Sign In with Apple (Expo, SwiftUI, `expo-apple-authentication`). Prevents rejecting valid native tokens; web OAuth unchanged. - **Bug Fixes** - In `verifyIdToken`, accept raw `nonce` or `sha256(raw)` via new `sha256Hex` and `nonceMatches`; added tests for raw, hashed, and mismatch cases. Fixes #7550. - **Dependencies** - Changeset for `@better-auth/core` patch release. <sup>Written for commit 7765348acac0817a128ba586dfe2def367483aaf. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-13 10:33:04 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#16512