rn-authlisted
Install: claude install-skill aiskillstore/marketplace
# React Native Authentication (Expo)
## Core Patterns
### Expo AuthSession for OAuth
Use `expo-auth-session` with `expo-web-browser` for OAuth flows:
```typescript
import * as AuthSession from 'expo-auth-session';
import * as WebBrowser from 'expo-web-browser';
import * as Google from 'expo-auth-session/providers/google';
// Critical: Call this at module level for proper redirect handling
WebBrowser.maybeCompleteAuthSession();
// Inside component
const [request, response, promptAsync] = Google.useAuthRequest({
iosClientId: 'YOUR_IOS_CLIENT_ID.apps.googleusercontent.com',
webClientId: 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com', // For backend verification
scopes: ['profile', 'email'],
});
```
### Common Pitfalls
1. **Missing `maybeCompleteAuthSession()`** - Auth redirects fail silently without this at module level
2. **Wrong client ID** - iOS needs the iOS client ID, but backend verification needs the web client ID
3. **Scheme mismatch** - `app.json` scheme must match Google Cloud Console redirect URI
4. **Expo Go vs standalone** - Different redirect URIs; use `AuthSession.makeRedirectUri()` to handle both
### Token Storage
Use `expo-secure-store` for tokens (not AsyncStorage):
```typescript
import * as SecureStore from 'expo-secure-store';
const TOKEN_KEY = 'auth_token';
const REFRESH_KEY = 'refresh_token';
export const tokenStorage = {
async save(token: string, refresh?: string) {
await SecureStore.setItemAsync(TOKEN_KEY, token);
if (refresh