Configurar autenticación con tokens JWT en gRPC

Lectura
20 min~5 min lectura

Concepto clave

La autenticación con JWT (JSON Web Tokens) en gRPC es un mecanismo para verificar la identidad de clientes que se comunican con tus microservicios. Imagina que cada servicio es un edificio de oficinas seguro: el JWT es como una credencial temporal que los visitantes (clientes) deben presentar en la entrada (interceptor) antes de poder acceder a las salas (métodos RPC).

Los JWT son tokens compactos y autónomos que contienen tres partes separadas por puntos: un header (que especifica el algoritmo de firma), un payload (con claims como usuario, roles y expiración), y una firma (que valida la integridad). A diferencia de las sesiones tradicionales, no requieren almacenamiento en el servidor, lo que los hace ideales para arquitecturas distribuidas donde los servicios pueden escalar independientemente.

En producción, los JWT suelen tener una vida útil corta (ej., 15 minutos) para minimizar riesgos si son comprometidos, y se combinan con refresh tokens para renovación segura.

Cómo funciona en la práctica

Para implementar autenticación JWT en gRPC, sigues un flujo estandarizado que involucra tanto el cliente como el servidor. Aquí está el proceso paso a paso:

  1. Generación del token: Un servicio de autenticación (como Auth Service) emite un JWT cuando un usuario inicia sesión, firmándolo con una clave secreta o privada.
  2. Inserción en metadata: El cliente incluye el JWT en los metadatos de la solicitud gRPC, típicamente en el header authorization con el prefijo Bearer.
  3. Intercepción en el servidor: Un interceptor en el servidor gRPC captura los metadatos, extrae el token, y lo valida (verificando firma, expiración y claims).
  4. Autorización: Basado en claims como roles, el servidor decide si permitir o denegar la llamada al método RPC.
  5. Respuesta: Si es válido, la solicitud procede; si no, se devuelve un error UNAUTHENTICATED o similar.

Ejemplo de metadata en Go:

md := metadata.Pairs("authorization", "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...")

Caso de estudio

Considera un sistema de microservicios para un e-commerce con servicios de Pedidos, Inventario y Pagos. Implementamos autenticación JWT para asegurar que solo usuarios autenticados puedan realizar acciones críticas.

ServicioMétodo gRPCClaim requeridoAcción
PedidosCreateOrderuser_id, role:customerCrear nuevo pedido
InventarioUpdateStockrole:adminModificar niveles de stock
PagosProcessPaymentuser_id, role:customerProcesar pago seguro

Flujo: Un usuario inicia sesión en el Auth Service, recibe un JWT, y lo usa para llamar a CreateOrder. El interceptor en el servicio Pedidos valida el token y verifica que el claim role sea customer. Si es admin, podría también acceder a UpdateStock. Esto previene accesos no autorizados y centraliza la lógica de autenticación.

Errores comunes

  • No validar la firma del JWT: Aceptar tokens sin verificar la firma permite a atacantes modificar claims. Siempre usa claves seguras y algoritmos como HS256 o RS256.
  • Ignorar la expiración (exp claim): Tokens expirados deben ser rechazados inmediatamente. Configura validación automática en librerías como jwt-go en Go o jsonwebtoken en Node.js.
  • Exponer secretos en código Almacenar claves de firma en repositorios públicos. Usa variables de entorno o servicios como AWS Secrets Manager.
  • Falta de manejo de errores en interceptores: No proporcionar mensajes claros cuando la autenticación falla, dificultando el debugging. Devuelve errores gRPC estándar como UNAUTHENTICATED con detalles.
  • No usar HTTPS en producción: Transmitir JWT sobre HTTP los expone a sniffing. Siempre habilita TLS/SSL en tus canales gRPC.

Checklist de dominio

  1. ¿Puedes generar un JWT válido con claims personalizados usando una librería estándar en tu lenguaje?
  2. ¿Implementaste un interceptor de servidor gRPC que extrae y valida tokens JWT de los metadatos?
  3. ¿Configuraste la inclusión automática de JWT en metadatos desde el cliente gRPC?
  4. ¿Manejas errores de autenticación devolviendo códigos de estado gRPC apropiados?
  5. ¿Probaste flujos con tokens expirados, inválidos o sin token para verificar robustez?
  6. ¿Aseguraste que las claves de firma estén protegidas y rotadas periódicamente?
  7. ¿Documentaste los claims requeridos para cada método RPC en tu API?

Implementa un interceptor de autenticación JWT en un servicio gRPC existente

En este ejercicio, agregarás autenticación JWT a un servicio gRPC simple que gestiona usuarios. Sigue estos pasos:

  1. Prepara el entorno: Clona un repositorio base (ej., en Go o Node.js) que tenga un servicio gRPC con métodos como GetUser y UpdateUser. Asegúrate de tener instaladas las dependencias necesarias, como librerías JWT.
  2. Genera tokens de prueba: Crea un script que genere dos JWT: uno válido con claim role:admin y expiración en 1 hora, y otro expirado. Usa una clave secreta my_secret_key y algoritmo HS256.
  3. Implementa el interceptor de servidor: En el servidor gRPC, escribe un interceptor que:
    • Extraiga el token del header authorization en los metadatos.
    • Valide la firma, expiración, y verifique que el claim role sea admin para métodos sensibles como UpdateUser.
    • Devuelva error UNAUTHENTICATED si el token es inválido o falta, o PERMISSION_DENIED si el rol es incorrecto.
  4. Modifica el cliente: Actualiza el cliente para incluir el token válido en los metadatos al llamar a UpdateUser. Prueba con el token expirado y observa los errores.
  5. Prueba y verifica: Ejecuta el servidor y cliente, confirmando que:
    • Las llamadas con token válido funcionan.
    • Las llamadas sin token o con token inválido fallan con errores claros.
    • El claim de rol se aplica correctamente (ej., un token con role:user no puede acceder a UpdateUser).
Pistas
  • Usa la librería estándar de JWT para tu lenguaje (ej., github.com/golang-jwt/jwt para Go) para simplificar la validación.
  • En los metadatos gRPC, el header debe estar en minúsculas: 'authorization'.
  • Para métodos que no requieren autenticación (ej., salud), puedes omitir el interceptor o manejarlo condicionalmente.

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.