← Volver al Blog

JWT Actualizar rotación de token: patrón seguro para sistemas reales

Seguridad del desarrollador28 de marzo de 2026·9 lectura mínima
JWT refresh token rotation diagram

La mayoría de los tutoriales de JWT se detienen en "usar un token de actualización para sesiones de larga duración". Rara vez explican qué sucede cuando se roba ese token de actualización. Un token de actualización estático (uno que nunca cambia) le da al atacante el mismo acceso persistente que una cookie de sesión robada. Peor aún, no hay forma de detectar el robo.

Rotación de token de actualización resuelve este problema emitiendo un nuevo token de actualización con cada uso. Si se reproduce un token antiguo, se revoca toda la sesión. Este artículo explica el patrón de implementación utilizado por Auth0, Okta y otros proveedores de identidad serios.

Por qué fallan los tokens de actualización estática

Un token de actualización estático tiene un valor fijo durante toda la vida útil de la sesión (a menudo, más de 30 días). Problemas:

La solución es tratar cada token de actualización como de un solo uso.

El modelo de rotación

Paso 1: Iniciar sesión: crear una familia de tokens

Cuando el usuario se autentica, genera un family_id (UUID) que agrupa todos los tokens en esta sesión:

{ family_id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", user_id: "user_123", refresh_token_hash: sha256(refresh_token), created_at: "2026-03-28T10:00:00Z", expires_at: "2026-04-27T10:00:00Z", used: false
}

Almacena este registro en el lado del servidor. Nunca almacene tokens de actualización en localStorage: utilice cookies httpOnly o almacenamiento nativo seguro.

Paso 2: Actualización del token: rotar

Cuando el cliente presenta el token de actualización:

  1. Busca el hash del token en la base de datos
  2. Verifique que pertenece a una familia activa y que no está marcado como usado
  3. Marcarlo como usado: verdadero
  4. Emitir un nuevo token de actualización (nuevo valor aleatorio, mismo family_id)
  5. Emitir un nuevo token de acceso
  6. Almacena el nuevo hash del token de actualización

Paso 3: Detección de repetición

Si se presenta nuevamente un token de actualización marcado como usado: true, esto significa:

La respuesta segura: revocar todos los tokens de la familia. Esto obliga al usuario a iniciar sesión nuevamente. Es mejor causarle molestias a un usuario legítimo una vez que permitir que un atacante mantenga el acceso.

// Repetición detectada: opción nuclear
esperar db.query ( 'ELIMINAR DE refresco_tokens DONDE family_id = $1', [ID de familia]
);

Esquema de base de datos

Una tabla de tokens de actualización mínima:

CREAR TABLA refresco_tokens ( id UUID CLAVE PRIMARIA POR DEFECTO gen_random_uuid(), family_id UUID NO NULO, user_id UUID NO REFERENCIAS NULAS usuarios(id), token_hash TEXTO NO NULO ÚNICO, usado BOOLEANO POR DEFECTO FALSO, creado_en TIMESTAMPTZ DEFAULT ahora(), expires_at TIMESTAMPTZ NO NULO, reemplazado_por REFERENCIAS UUID actualizar_tokens(id)
); CREAR ÍNDICE idx_refresh_family EN refresco_tokens(family_id);
CREAR ÍNDICE idx_refresh_user EN actualizar_tokens(user_id);

La columna replaced_by crea una cadena que puede seguir con fines de auditoría.

Manejo de solicitudes simultáneas

En aplicaciones reales, varias llamadas API pueden activar una actualización simultáneamente. Si la Llamada A rota el token mientras la Llamada B todavía retiene el antiguo, la Llamada B activa la detección de repetición, lo que cierra la sesión del usuario inesperadamente.

Patrón de período de gracia

Permitir que el token de actualización anterior siga siendo válido durante un período breve (de 5 a 10 segundos) después de la rotación:

const GRACE_PERIOD_MS = 10_000; si (token.usado) { const transcurrido = Fecha.ahora() - token.rotated_at; si (transcurrido < GRACE_PERIOD_MS) { // Within grace period — return the already-issued new tokens return getLatestTokensForFamily(token.family_id); } // Outside grace period — replay attack await revokeFamily(token.family_id); throw new UnauthorizedError('token_replayed');
}

Monitoreo y Alertas

Seguimiento de estas señales en producción:

Token de actualización frente a token de acceso: referencia rápida

PropiedadToken de accesoToken de actualización
Vida útil5–15 minutos7–30 días
FormatoJWT (autónomo)Cadena opaca (recomendado)
AlmacenamientoMemoria (variable JS)httpOnly cookie
Enviado aServidores APISolo servidor de autenticación
RotaciónNo es necesarioCada uso

Para errores de validación de reclamación de tiempo que a menudo interactúan con los flujos de actualización, consulte JWT exp/iat/nbf errores comunes.

Preguntas frecuentes

¿Cómo debo manejar las solicitudes de actualización simultáneas?

Utilice un período de gracia breve (de 5 a 10 segundos) en el que aún se acepte el token de actualización anterior. Esto maneja las condiciones de carrera cuando varias llamadas API activan una actualización simultáneamente. Después del período de gracia, solo es válido el token más nuevo.

¿Los tokens de actualización deben ser JWT o cadenas opacas?

Las cadenas opacas generalmente son más seguras para los tokens de actualización. Los JWT transportan datos de carga útil que aumentan la superficie de ataque y los tokens de actualización no necesitan ser autónomos, ya que el servidor siempre los busca en la base de datos de todos modos.

¿Cuánto tiempo deben durar las sesiones de actualización?

Lo típico es

7–30 días. Las aplicaciones de alta seguridad (banca, atención médica) deberían tardar entre 1 y 7 días. Las aplicaciones para consumidores pueden durar hasta 90 días con rotación. Empareje siempre sesiones largas con huellas dactilares del dispositivo y detección de anomalías.

Herramientas y artículos relacionados