Tipos de Metodos de Autenticacion - Comparacion de Sesion, Token y OAuth

16 min de lectura | 2025.12.08

Diferencia entre Autenticacion y Autorizacion

Primero, vamos a clarificar dos conceptos que a menudo se confunden.

  • Autenticacion (Authentication): “Quien eres?” - Verificar la identidad del usuario
  • Autorizacion (Authorization): “Que puedes hacer?” - Verificar permisos de acceso
flowchart LR
    A[Login] --> B[Autenticacion<br/>Verificar identidad con ID/Contrasena]
    B --> C[Operacion]
    C --> D[Autorizacion<br/>Verificar si tiene permiso para esta operacion]

Comparacion de Metodos de Autenticacion

MetodoGestion de EstadoCaso Adecuado
Autenticacion por SesionLado del servidorAplicaciones web tradicionales
Autenticacion por Token (JWT)Lado del clienteSPA, aplicaciones moviles
OAuth 2.0Servicio externoAutenticacion de terceros, integracion de API

Autenticacion por Sesion

Funcionamiento

sequenceDiagram
    participant C as Cliente
    participant S as Servidor
    participant Store as Almacen de Sesiones

    rect rgb(240, 248, 255)
        Note over C,Store: 1. Login
        C->>S: Enviar ID/Contrasena
        S->>S: Autenticar
        S->>Store: Generar y guardar ID de sesion
        S->>C: Set-Cookie: session_id=abc123
    end

    rect rgb(245, 255, 245)
        Note over C,Store: 2. Solicitudes posteriores
        C->>S: Cookie: session_id=abc123
        S->>Store: Verificar ID de sesion
        Store->>S: Resultado de verificacion
    end

Ejemplo de Implementacion

// Express.js + express-session
const session = require('express-session');
const RedisStore = require('connect-redis').default;

app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: true,      // Requiere HTTPS
    httpOnly: true,    // No accesible desde JS
    sameSite: 'strict', // Proteccion CSRF
    maxAge: 24 * 60 * 60 * 1000 // 24 horas
  }
}));

// Login
app.post('/login', async (req, res) => {
  const user = await authenticate(req.body);
  if (user) {
    req.session.userId = user.id;
    res.json({ success: true });
  }
});

Ventajas y Desventajas

VentajasDesventajas
Facil invalidar sesionesRequiere gestion de estado en el servidor
Facil control de seguridadRequiere compartir sesiones en entornos distribuidos
Implementacion simpleMala compatibilidad con aplicaciones moviles

Autenticacion por Token (JWT)

Funcionamiento

sequenceDiagram
    participant C as Cliente
    participant S as Servidor

    rect rgb(240, 248, 255)
        Note over C,S: 1. Login
        C->>S: Enviar ID/Contrasena
        S->>S: Autenticar → Generar JWT (firmado)
        S->>C: { "token": "eyJhbG..." }
    end

    rect rgb(245, 255, 245)
        Note over C,S: 2. Solicitudes posteriores
        C->>S: Authorization: Bearer eyJhbG...
        S->>S: Verificar firma del JWT (sin acceso al almacen)
    end

Estructura del JWT

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.     ← Header
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6...   ← Payload
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c ← Firma

Header (decodificado Base64):
{ "alg": "HS256", "typ": "JWT" }

Payload (decodificado Base64):
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022,
  "exp": 1516325422
}

Ejemplo de Implementacion

const jwt = require('jsonwebtoken');

// Generacion de token
app.post('/login', async (req, res) => {
  const user = await authenticate(req.body);
  if (user) {
    const token = jwt.sign(
      { userId: user.id, role: user.role },
      process.env.JWT_SECRET,
      { expiresIn: '1h' }
    );
    res.json({ token });
  }
});

// Middleware de verificacion de token
function authMiddleware(req, res, next) {
  const token = req.headers.authorization?.split(' ')[1];
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    next();
  } catch (error) {
    res.status(401).json({ error: 'Invalid token' });
  }
}

Refresh Token

flowchart TD
    subgraph Tokens["Tiempo de expiracion de tokens"]
        AT["Access Token<br/>Corta duracion (15 min - 1 hora)"]
        RT["Refresh Token<br/>Larga duracion (7 - 30 dias), almacenado de forma segura"]
    end

    A[Access Token expirado] --> B[Obtener nuevo Access Token con Refresh Token]
    B --> C{Refresh Token tambien expirado?}
    C -->|Si| D[Re-login]
    C -->|No| E[Continuar con nuevo Access Token]

Ventajas y Desventajas

VentajasDesventajas
Sin estado, facil de escalarDificil invalidar tokens
Adecuado para sistemas distribuidosTamano del token grande
Adecuado para movil/SPAEl payload no esta encriptado

OAuth 2.0

Descripcion General

Es un mecanismo de autenticacion y autorizacion que utiliza servicios de terceros (Google, GitHub, etc.).

sequenceDiagram
    participant U as Usuario
    participant A as Tu Aplicacion<br/>(Client)
    participant AS as Servidor de Autorizacion<br/>(Google, etc.)

    U->>A: 1. Clic en boton de login
    A->>AS: 2. Solicitud de autorizacion
    AS->>U: 3. Pantalla de login
    U->>AS: 4. Autenticacion y consentimiento
    AS->>A: 5. Codigo de autorizacion
    A->>AS: 6. Solicitud de token
    AS->>A: 7. Access token
    A->>U: 8. Login completado

Ejemplo de Implementacion (Authorization Code Flow)

// 1. Solicitud de autorizacion
app.get('/auth/google', (req, res) => {
  const authUrl = new URL('https://accounts.google.com/o/oauth2/v2/auth');
  authUrl.searchParams.set('client_id', process.env.GOOGLE_CLIENT_ID);
  authUrl.searchParams.set('redirect_uri', 'https://myapp.com/callback');
  authUrl.searchParams.set('response_type', 'code');
  authUrl.searchParams.set('scope', 'openid email profile');
  authUrl.searchParams.set('state', generateState());
  res.redirect(authUrl.toString());
});

// 2. Procesamiento del callback
app.get('/callback', async (req, res) => {
  const { code, state } = req.query;
  verifyState(state);

  // Intercambio de token
  const tokenResponse = await fetch('https://oauth2.googleapis.com/token', {
    method: 'POST',
    body: new URLSearchParams({
      client_id: process.env.GOOGLE_CLIENT_ID,
      client_secret: process.env.GOOGLE_CLIENT_SECRET,
      code,
      grant_type: 'authorization_code',
      redirect_uri: 'https://myapp.com/callback'
    })
  });

  const { access_token, id_token } = await tokenResponse.json();
  // Obtener informacion del usuario y crear sesion
});

Tipos de Grant

Tipo de GrantUso
Authorization CodeAplicaciones web (mas comun)
PKCESPA, aplicaciones moviles
Client CredentialsComunicacion entre servidores
Device CodeDispositivos con entrada limitada como Smart TV

Como Elegir el Metodo de Autenticacion

flowchart LR
    subgraph Apps["Tipo de Aplicacion"]
        A1["Aplicacion web tradicional<br/>(Server-side rendering)"]
        A2["SPA + API"]
        A3["Aplicacion movil"]
        A4["Login de terceros<br/>(Login con Google, etc.)"]
        A5["Comunicacion entre microservicios"]
    end

    subgraph Auth["Metodo de Autenticacion Recomendado"]
        B1["Autenticacion por Sesion"]
        B2["JWT<br/>(Access Token de corta duracion + Refresh Token)"]
        B3["JWT o OAuth 2.0 (PKCE)"]
        B4["OAuth 2.0 / OpenID Connect"]
        B5["JWT o OAuth 2.0<br/>(Client Credentials)"]
    end

    A1 --> B1
    A2 --> B2
    A3 --> B3
    A4 --> B4
    A5 --> B5

Resumen

La eleccion del metodo de autenticacion depende del tipo de aplicacion, requisitos de seguridad y requisitos de escalabilidad. La autenticacion por sesion es simple de implementar y facil de controlar, mientras que JWT es sin estado y facil de escalar. OAuth 2.0 es optimo para autenticacion de terceros e integracion de API. Entendamos las caracteristicas de cada uno y elijamos el metodo apropiado.

← Volver a la lista