10 ejemplos para comenzar con autenticación móvil - 7 básicos e intermedios 3. Cubre modelos de sesión, dónde viven los tokens en el dispositivo, y qué significa cierre de sesión en todas partes cuando los usuarios cambian de cuenta o revocan acceso.
Las aplicaciones móviles típicamente usan una de tres formas de sesión. Elige según tu backend - no inventes una cuarta a menos que el cumplimiento lo exija.
Los tokens de acceso autorizan llamadas API. Los tokens de actualización obtienen nuevos tokens de acceso - son de mayor valor y deben almacenarse más cuidadosamente.
Los niveles de almacenamiento móvil tienen diferentes modelos de amenaza. Haz coincidir la sensibilidad con el almacén.
┌──────────────────┬────────────────────────────────────────────────┐│ Almacenar │ Apropiado para │├──────────────────┼────────────────────────────────────────────────┤│ Estado React │ Acceso en memoria token de acceso durante sesión activa ││ expo-secure-store│ Tokens de actualización, secretos de larga duración ││ AsyncStorage │ Tema, banderas de incorporación, preferencias no sensibles ││ MMKV (cifrado) │ Cachés grandes - no es sustituto de Keychain ││ expo-file-system │ Archivos, medios - nunca tokens sin procesar │└──────────────────┴────────────────────────────────────────────────┘
import * as SecureStore from "expo-secure-store";const REFRESH_KEY = "auth.refresh_token";export async function saveRefreshToken(token: string) { await SecureStore.setItemAsync(REFRESH_KEY, token, { keychainAccessible: SecureStore.WHEN_UNLOCKED_THIS_DEVICE_ONLY, });}export async function loadRefreshToken() { return SecureStore.getItemAsync(REFRESH_KEY);}
Secure Store se asigna a iOS Keychain y Android Keystore - respaldado por hardware en dispositivos compatibles
AsyncStorage es SQLite sin cifrar - está bien para hasSeenOnboarding, fatal para tokens de actualización
En memoria los tokens de acceso desaparecen al matar el proceso - empareja con actualización silenciosa al inicio en frío
Audita PRs para AsyncStorage.setItem con nombres de clave similares a tokens
El cierre de sesión local borra artefactos del dispositivo y estado en memoria. Es el mínimo que cada aplicación debe implementar.
// src/features/auth/api/signOutLocal.tsimport * as SecureStore from "expo-secure-store";const AUTH_KEYS = ["auth.refresh_token", "auth.device_binding_id"] as const;export async function signOutLocal() { await Promise.all(AUTH_KEYS.map((key) => SecureStore.deleteItemAsync(key)));}
// En tu pantalla de configuraciónimport { useAuth } from "../AuthProvider";import { signOutLocal } from "../api/signOutLocal";async function handleSignOut() { await signOutLocal(); setSession(null); // del setter de estado del proveedor de autenticación expuesto via contexto router.replace("/sign-in");}
Borra cada clave de secure-store que tu flujo de autenticación escribió - actualización, vinculación de dispositivo, banderas de desbloqueo biométrico
Restablece navegación a la pila de inicio de sesión - Android back no debe regresar a pantallas autenticadas
Limpiar estado React solamente es insuficiente - los usuarios reinician en un shell autenticado con tokens obsoletos
Empareja con queryClient.clear() de TanStack Query cuando cachés respaldados por servidor contienen PII de usuario
Ya sea que los usuarios inicien sesión con correo electrónico o Google, normaliza a un tipo Session para que el resto de la aplicación permanezca agnóstica del proveedor.
¿Debo almacenar también el token de acceso en secure store?
En memoria es suficiente para la mayoría de aplicaciones si el inicio en frío siempre se actualiza.
Persiste token de acceso solo cuando tu backend no puede actualizar frecuentemente y la UX exige lecturas sin conexión - aún prefiere TTL corto.
¿Es Expo Go seguro para probar flujos de autenticación?
Los URI de redirección de OAuth difieren entre Expo Go y compilaciones independientes - prueba en una compilación de desarrollo antes del lanzamiento.
Secure Store funciona en Expo Go, pero esquemas de URL personalizados para OAuth requieren configuración de redirección expo-auth-session por entorno.
¿Cuál es la diferencia entre cerrar sesión y revocar?
Cerrar sesión borra este dispositivo.
Revocar / logout everywhere invalida tokens de actualización del lado del servidor para todos los dispositivos - requerido para escenarios de dispositivo robado.
¿Puedo usar claims de JWT para autorización en el cliente?
Decodifica claims solo para UX (nombre para mostrar, avatar).
Nunca confíes en verificaciones de rol del lado del cliente para seguridad - servidor valida cada solicitud.
¿Dónde van las claves API?
Claves públicas en EXPO_PUBLIC_* solo si se diseñan para exposición del cliente.
Nunca pongas secretos de cliente OAuth en la aplicación - intercambia códigos en tu backend.