Estado
El estado del paquete es Paquete actual. Los adaptadores Expo SecureStore y WebBrowser, XidProvider y el hook guard de rutas para Expo Router están implementados. Una prueba de ida y vuelta real contra un IdP en infraestructura de producción está pendiente de verificación manual.
Toda la lógica PKCE, el intercambio de tokens y la gestión de sesiones viven en @xid-kit/react-native; este paquete solo provee adaptadores e integración con Expo Router.
Configuración del proveedor
Inyecta createSecureStoreAdapter y createExpoWebBrowserAdapter en XidProvider. No se necesita importar el módulo Expo en el nivel raíz; los adaptadores aceptan instancias de módulo para que el typecheck en CI funcione sin las dependencias peer de Expo instaladas.
import * as SecureStore from 'expo-secure-store'
import * as WebBrowser from 'expo-web-browser'
import { XidProvider, createSecureStoreAdapter, createExpoWebBrowserAdapter } from '@xid-kit/expo'
const tokenCache = createSecureStoreAdapter({ secureStore: SecureStore })
const browser = createExpoWebBrowserAdapter({ webBrowser: WebBrowser })
export default function App() {
return (
<XidProvider
publishableKey="pk_live_..."
issuer="https://xid.dev"
clientId="your_client_id"
redirectUri="myapp://auth/callback"
tokenCache={tokenCache}
browser={browser}
>
<RootLayout />
</XidProvider>
)
}Inicio y cierre de sesión
import { useSignIn, useSignOut } from '@xid-kit/expo'
import { Button } from 'react-native'
function SignInScreen() {
const { signIn, signInState } = useSignIn()
return (
<Button
title={signInState.status === 'pending' ? 'Signing in...' : 'Sign In'}
onPress={() => void signIn()}
/>
)
}
function SignOutScreen() {
const { signOut } = useSignOut()
return <Button title="Sign Out" onPress={() => void signOut()} />
}Guard de rutas de Expo Router
Llama a useProtectedRoute en un componente de layout. Lee isLoaded/isSignedIn desde useAuth y llama a replace de Expo Router dentro de un useEffect.
import { useProtectedRoute } from '@xid-kit/expo'
import { useRouter, usePathname } from 'expo-router'
export default function RootLayout() {
const router = useRouter()
const pathname = usePathname()
useProtectedRoute({
signInRoute: '/sign-in',
protectedRoute: '/(app)',
pathname,
replace: router.replace,
})
return <Slot />
}Espaciado de nombres de claves SecureStore
Usa keyPrefix para agrupar las claves bajo un prefijo personalizado. El separador es . (punto), que está dentro del conjunto de caracteres permitidos por expo-secure-store.
const tokenCache = createSecureStoreAdapter({
secureStore: SecureStore,
keyPrefix: 'myapp',
// keys: 'myapp.xid.access_token', 'myapp.xid.refresh_token', etc.
})API exportada
| Exportar | Tipo | Propósito |
|---|---|---|
XidProvider |
componente | Re-exportación de XidProvider de @xid-kit/react-native que acepta adaptadores tokenCache y browser |
createSecureStoreAdapter |
function | Adaptador TokenCache respaldado por expo-secure-store; acepta una instancia secureStore y un keyPrefix opcional |
createExpoWebBrowserAdapter |
function | Adaptador BrowserInterface respaldado por expo-web-browser |
useSignIn |
hook | Re-exportación de @xid-kit/react-native: signIn, handleRedirect, signInState |
useSignOut |
hook | Re-exportación de @xid-kit/react-native: signOut, signOutState |
useProtectedRoute |
hook | Lee isLoaded/isSignedIn y llama al replace de Expo Router para proteger rutas |
Limitaciones conocidas
useAuth().isSignedInrefleja el estado de sesión por cookie web deXidClient, que no se rellena automáticamente desde los tokens locales de SecureStore tras el intercambio. Recarga el estado del cliente explícitamente tras un inicio de sesión exitoso.- Este paquete solo proporciona adaptadores e integración con Expo Router. Para el flujo PKCE base de React Native, consulta @xid-kit/react-native.