[GH-ISSUE #9179] tracking: Expo/RN OAuth (SecureStore, deep-link callback, stateless regressions) #28620

Open
opened 2026-04-17 20:03:13 -05:00 by GiteaMirror · 0 comments
Owner

Originally created by @gustavovalverde on GitHub (Apr 14, 2026).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/9179

Summary

Expo and React Native OAuth flows fail during session persistence, callback return, Apple id-token validation, and stateless session completion. Session data is written to SecureStore but is not always available after app restart. Some OAuth completions do not return to the app after browser-based authentication. Apple id-tokens submitted through expo-apple-authentication can fail server-side validation. Stateless flows that use storeStateStrategy: "cookie" with customSession changed behavior between 1.4.17 and 1.6.x.

Root cause

The Expo plugin combines SecureStore persistence, cookie serialization, and deep-link callback handling in the same flow. Those paths fail independently. SecureStore persistence is not exercised on app cold-start. The cookie serializer can emit a leading semicolon that upstream infrastructure rejects. Android deep-link return is not invoked when linkSocial uses the system browser path. The stateless regression points to a change in how customSession interacts with storeStateStrategy: "cookie" between 1.4.17 and 1.6.x.

Scope

In: Expo and RN OAuth callback completion on iOS and Android, SecureStore read/write symmetry, cookie-serialization correctness in the Expo plugin, stateless OAuth behaviour when the Expo plugin is active.

Out: OAuth state cookie writes on web (handled in the OAuth state_mismatch family, see cross-reference on #6847). Session cookie-cache lifecycle (see tracking: session cookie cache). Non-Expo RN integrations without the expo() plugin.

Resolution criteria

  • App cold-start reads back session data from SecureStore without re-login.
  • linkSocial on Android returns via openAuthSessionAsync, not the system browser.
  • Apple id-token submitted from expo-apple-authentication is validated server-side without "Invalid id token".
  • Google OAuth completion after 2FA reaches the RN deep-link handler on both platforms.
  • Expo + customSession + storeStateStrategy: "cookie" behaves the same on 1.6.x as on 1.4.17.
  • Bridge case across OAuth state: #6847 (Expo + stateless + Android state_mismatch).
  • Prior closed context: #6810 (SecureStore format), #8407 (Android linking path), #7674 (malformed cookie), #7240 (subdomain persistence), #8194 (private state access), #7791 (private-api device-id).
Originally created by @gustavovalverde on GitHub (Apr 14, 2026). Original GitHub issue: https://github.com/better-auth/better-auth/issues/9179 ## Summary Expo and React Native OAuth flows fail during session persistence, callback return, Apple id-token validation, and stateless session completion. Session data is written to SecureStore but is not always available after app restart. Some OAuth completions do not return to the app after browser-based authentication. Apple id-tokens submitted through `expo-apple-authentication` can fail server-side validation. Stateless flows that use `storeStateStrategy: "cookie"` with `customSession` changed behavior between 1.4.17 and 1.6.x. ## Root cause The Expo plugin combines SecureStore persistence, cookie serialization, and deep-link callback handling in the same flow. Those paths fail independently. SecureStore persistence is not exercised on app cold-start. The cookie serializer can emit a leading semicolon that upstream infrastructure rejects. Android deep-link return is not invoked when `linkSocial` uses the system browser path. The stateless regression points to a change in how `customSession` interacts with `storeStateStrategy: "cookie"` between 1.4.17 and 1.6.x. ## Scope **In:** Expo and RN OAuth callback completion on iOS and Android, SecureStore read/write symmetry, cookie-serialization correctness in the Expo plugin, stateless OAuth behaviour when the Expo plugin is active. **Out:** OAuth state cookie writes on web (handled in the `OAuth state_mismatch` family, see cross-reference on #6847). Session cookie-cache lifecycle (see `tracking: session cookie cache`). Non-Expo RN integrations without the `expo()` plugin. ## Resolution criteria - App cold-start reads back session data from SecureStore without re-login. - `linkSocial` on Android returns via `openAuthSessionAsync`, not the system browser. - Apple id-token submitted from `expo-apple-authentication` is validated server-side without "Invalid id token". - Google OAuth completion after 2FA reaches the RN deep-link handler on both platforms. - Expo + `customSession` + `storeStateStrategy: "cookie"` behaves the same on 1.6.x as on 1.4.17. ## Related - Bridge case across OAuth state: #6847 (Expo + stateless + Android state_mismatch). - Prior closed context: #6810 (SecureStore format), #8407 (Android linking path), #7674 (malformed cookie), #7240 (subdomain persistence), #8194 (private state access), #7791 (private-api device-id).
GiteaMirror added the trackingplatformoauth labels 2026-04-17 20:03:14 -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#28620