React Native
React Native can’t use cookies, so we use bearer mode with secure storage for the refresh token.
-
Install packages
npm install authfort-client expo-secure-storenpm install authfort-client expo-secure-store -
Create the auth client with secure storage
src/auth.tsimport { createAuthClient } from 'authfort-client'; import * as SecureStore from 'expo-secure-store'; export const auth = createAuthClient({ baseUrl: 'https://api.yourapp.com/auth', tokenMode: 'bearer', tokenStorage: { get: () => SecureStore.getItemAsync('refresh_token'), set: (token) => SecureStore.setItemAsync('refresh_token', token), clear: () => SecureStore.deleteItemAsync('refresh_token'), }, });import { createAuthClient } from 'authfort-client'; import * as SecureStore from 'expo-secure-store'; export const auth = createAuthClient({ baseUrl: 'https://api.yourapp.com/auth', tokenMode: 'bearer', tokenStorage: { get: () => SecureStore.getItemAsync('refresh_token'), set: (token) => SecureStore.setItemAsync('refresh_token', token), clear: () => SecureStore.deleteItemAsync('refresh_token'), }, }); -
Wrap with AuthProvider
App.tsximport { AuthProvider } from 'authfort-client/react'; import { auth } from './src/auth'; auth.initialize(); export default function App() { return ( <AuthProvider client={auth}> <Navigation /> </AuthProvider> ); }import { AuthProvider } from 'authfort-client/react'; import { auth } from './src/auth'; auth.initialize(); export default function App() { return ( <AuthProvider client={auth}> <Navigation /> </AuthProvider> ); }
The useAuth hook works the same as on web:
import { useAuth } from 'authfort-client/react';
function ProfileScreen() {
const { user, isAuthenticated, isLoading, client } = useAuth();
if (isLoading) return <ActivityIndicator />;
if (!isAuthenticated) return <LoginScreen />;
return (
<View>
<Text>Hello {user.email}</Text>
<Button title="Sign Out" onPress={() => client.signOut()} />
</View>
);
} import { useAuth } from 'authfort-client/react';
function ProfileScreen() {
const { user, isAuthenticated, isLoading, client } = useAuth();
if (isLoading) return <ActivityIndicator />;
if (!isAuthenticated) return <LoginScreen />;
return (
<View>
<Text>Hello {user.email}</Text>
<Button title="Sign Out" onPress={() => client.signOut()} />
</View>
);
} API Requests
Section titled “API Requests”Use auth.fetch() for authenticated requests:
const res = await auth.fetch('https://api.yourapp.com/api/profile');
const data = await res.json(); const res = await auth.fetch('https://api.yourapp.com/api/profile');
const data = await res.json(); Or use getToken() with your preferred HTTP client:
const token = await auth.getToken();
const res = await fetch('https://api.yourapp.com/api/profile', {
headers: { Authorization: `Bearer ${token}` },
}); const token = await auth.getToken();
const res = await fetch('https://api.yourapp.com/api/profile', {
headers: { Authorization: `Bearer ${token}` },
}); Why Bearer Mode?
Section titled “Why Bearer Mode?”React Native doesn’t have browser cookies. Bearer mode stores the access token in memory (never persisted) and the refresh token in expo-secure-store (encrypted on-device storage backed by iOS Keychain / Android Keystore).
Alternative: react-native-keychain
Section titled “Alternative: react-native-keychain”import * as Keychain from 'react-native-keychain';
const auth = createAuthClient({
baseUrl: 'https://api.yourapp.com/auth',
tokenMode: 'bearer',
tokenStorage: {
get: async () => {
const creds = await Keychain.getGenericPassword();
return creds ? creds.password : null;
},
set: (token) => Keychain.setGenericPassword('authfort', token),
clear: () => Keychain.resetGenericPassword().then(() => {}),
},
}); import * as Keychain from 'react-native-keychain';
const auth = createAuthClient({
baseUrl: 'https://api.yourapp.com/auth',
tokenMode: 'bearer',
tokenStorage: {
get: async () => {
const creds = await Keychain.getGenericPassword();
return creds ? creds.password : null;
},
set: (token) => Keychain.setGenericPassword('authfort', token),
clear: () => Keychain.resetGenericPassword().then(() => {}),
},
});