En aplicaciones modernas, web y móviles, el flujo de login se maneja comúnmente con Tokens, especialmente con JSON Web Tokens (JWT). Este enfoque permite que el usuario tenga una forma segura y eficiente de mantener su sesión activa sin necesidad de iniciar sesión constantemente.

Para entender mejor este flujo, es importante conocer algunos conceptos clave como: authenticate, authorization, Access Token y Refresh Token. Esto nos permitirá aplicar correctamente estas técnicas en nuestros proyectos y/o entrevistas técnicas.

¿Qué es Authenticate?

Authenticate (Auth) se refiere al proceso de verificar la identidad de un usuario mediante credenciales, como nombre de usuario y contraseña, el backend válida esta información y retorna los datos necesarios para el proyecto.

async function loginUser(...) {
  // ....
  return {
    "userId": "12345",
    "fullName": "Miguel",
  }
}

¿Qué es Authorization?

Authorization (AuthZ) es el proceso de determinar qué recursos o acciones tiene permitido un usuario autenticado. En el login, el backend retorna estos datos (como roles y permisos) para que sean incluidos en el Access Token.

async function loginUser(...) {
  // ....
  return {
      "userId": "12345",
      "fullName": "Miguel",
      "roles": ["admin", "editor"],
      "permissions": ["read:articles", "write:articles"],
  }
}

¿Qué es un Access Token?

Un Access Token es una llave temporal generada usando JWT que permite al usuario acceder a recursos protegidos de la aplicación. Los Access Tokens suelen tener una vida útil corta para minimizar riesgos de seguridad.

  • JWT (JSON Web Token): Es un estándar abierto y compacto (como un objeto JSON codificado) utilizado para transmitir información de manera segura entre dos partes. Se compone de tres partes: Header, Payload (Claims) y Signature.
  • Claims: Son las declaraciones o la información real (datos del usuario, permisos y tiempo de expiración) que el servidor codifica dentro del cuerpo del JWT.
Estructura de un JSON Web Token (JWT)

Imagen de referencia: Components of JWTs Explained

¿Qué es un Refresh Token?

Un Refresh Token es un token de larga duración que se utiliza para obtener nuevos Access Tokens una vez que estos han expirado. A diferencia del Access Token, el Refresh Token no se envía con cada solicitud, sino que se almacena de manera segura y se utiliza únicamente cuando es necesario renovar el Access Token.

Diagrama de flujo completo de login: auth, authorization, acccess token y refresh token

A continuación, se muestra un diagrama que ilustra el flujo completo de login y autenticación moderna con Tokens:

Diagrama de flujo de login y autenticación moderna con tokens

Ahora revisemos algunos de los pasos clave en este flujo:

¿Cómo se genera el access token y el refresh token?

El Access Token y el Refresh Token se generan en el backend después de un login exitoso del cliente (browser/app). Cada token contiene información codificada (claims) que el servidor puede usar para validar y autorizar al usuario.

  • accessToken: contiene información sobre el usuario y sus permisos, con una vida útil corta (por ejemplo, 15 minutos).
  • refreshToken: contiene información para identificar al usuario y tiene una vida útil más larga (por ejemplo, 7 días).
async function loginUser(...) {
  // ....
  return {
    // ...
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refreshToken": "dGhpcy1pcz1hLXJlZnJlc2gtdG9rZW4tZXhhbXBsZQ==",
  }
}

¿Cómo viaja el access token?

Este token se envía en cada HTTP request para verificar que el usuario tiene permiso para acceder a los datos solicitados, mediante el HTTP Authorization header Bearer <access_token>.

async function fetchReports() {
  // Obtener el access token desde el cliente (localStorage, cookies, etc.)
  const accessToken = getAccessToken();
  const response = await fetch('/api/v1/reports', {
    method: 'GET',
    headers: {
      Authorization: `Bearer ${accessToken}`,
    },
  });
  return response.json();
}

¿Qué pasa cuando el access token expira?

Cuando el Access Token expira, el servidor retornará un error 401 Unauthorized indicando que el token ya no es válido y necesitas un nuevo token para continuar accediendo a los recursos protegidos.

Uso del refresh token para obtener un nuevo access token

Cuando la aplicación detecta el error 401 Unauthorized, utilizaremos el Refresh Token para solicitar un nuevo Access Token al servidor si este aún es válido.

async function refreshAccessToken() {
  // Obtener el refresh token desde el cliente (localStorage, cookies, etc.)
  const refreshToken = getRefreshToken();
  const response = await fetch('/api/auth/refresh-token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ refreshToken }),
  });
  const data = await response.json();
  return data.accessToken;
}

async function fetchReports() {
  // ...
  if (response.status === 401) {
    const newAccessToken = await refreshAccessToken();
    // Reintentar la solicitud con el nuevo access token
    const retryResponse = await fetch('/api/v1/reports', {
      method: 'GET',
      headers: {
        Authorization: `Bearer ${newAccessToken}`,
      },
    });

    return retryResponse.json();
  }
  return response.json();
}

Rotación del refresh token

Por razones de seguridad, está práctica implica que el Refresh Token que se ha utilizado debe ser revocado(invalidado) inmediatamente y reemplazado por uno nuevo que el servidor también debe generar. Esto ayuda a prevenir ataques de reutilización de tokens.

Que pasa si el refresh token expira?

Cuando el Refresh Token también expira (o es revocado), el sistema ya no podrá continuar y el usuario deberá ser redirigido al login para volver a autenticarse y obtener nuevos tokens.

Buenas prácticas de seguridad con tokens

  • Access Token: En memoria, nunca en localStorage, para prevenir ataques XSS.
  • Refresh Token: En HTTP-Only Cookies (Secure).
  • Access Token: Duración corta (minutos).
  • Refresh Token: Aplica Rotación después de cada uso.
  • Backend: Siempre valida firma y expiración del Access Token.
  • Permite Revocación Forzada de sesiones (Logout remoto)

Gracias por leer, que tengas un día maravilloso! 🌞