diff --git a/.changeset/fix-clear-jwt-on-signout.md b/.changeset/fix-clear-jwt-on-signout.md new file mode 100644 index 00000000000..8be2e8ff496 --- /dev/null +++ b/.changeset/fix-clear-jwt-on-signout.md @@ -0,0 +1,5 @@ +--- +'@clerk/expo': patch +--- + +Clear JWT from SecureStore when signing out via native components (AuthView, UserButton) to prevent "session_exists" / "already signed in" errors on subsequent sign-in attempts. diff --git a/packages/expo/src/native/UserButton.tsx b/packages/expo/src/native/UserButton.tsx index 045d3027080..5f972f8f23f 100644 --- a/packages/expo/src/native/UserButton.tsx +++ b/packages/expo/src/native/UserButton.tsx @@ -1,7 +1,9 @@ import { useClerk, useUser } from '@clerk/react'; +import * as SecureStore from 'expo-secure-store'; import { useEffect, useRef, useState } from 'react'; import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; +import { CLERK_CLIENT_JWT_KEY } from '../constants'; import { ClerkExpoModule as ClerkExpo, isNativeSupported } from '../utils/native-module'; // Raw result from native module (may vary by platform) @@ -155,6 +157,9 @@ export function UserButton(_props: UserButtonProps) { } } + // Clear stale JWT from SecureStore to prevent "already signed in" errors + await SecureStore.deleteItemAsync(CLERK_CLIENT_JWT_KEY).catch(() => {}); + // Sign out from JS SDK to update isSignedIn state if (clerk?.signOut) { try { diff --git a/packages/expo/src/provider/ClerkProvider.tsx b/packages/expo/src/provider/ClerkProvider.tsx index 153cbbef18e..69ec965f3ac 100644 --- a/packages/expo/src/provider/ClerkProvider.tsx +++ b/packages/expo/src/provider/ClerkProvider.tsx @@ -10,6 +10,7 @@ import { CLERK_CLIENT_JWT_KEY } from '../constants'; import { useNativeAuthEvents } from '../hooks/useNativeAuthEvents'; import NativeClerkModule from '../specs/NativeClerkModule'; import { tokenCache as defaultTokenCache } from '../token-cache'; +import * as SecureStore from 'expo-secure-store'; import { isNative, isWeb } from '../utils/runtime'; import { getClerkInstance } from './singleton'; import type { BuildClerkOptions } from './singleton/types'; @@ -254,6 +255,9 @@ export function ClerkProvider(props: ClerkProviderProps {}); await clerkInstance.signOut(); } } catch (error) {