Files
fn_registry/functions/infra/jwt_middleware.md
T
egutierrez f46fde3656 feat: rbac_check (pure), jwt_middleware, rbac_middleware
Fase 5 del issue 0010 — RBAC y middlewares de auth.
- rbac_check es pura: solo recorre la matriz roles/permisos
- jwt_middleware extrae token del header Authorization: Bearer, valida e
  inyecta claims en el context con una key privada (jwtCtxKey struct{})
- rbac_middleware requiere jwt_middleware antes; lee role de claims.Custom
- Helper JWTClaimsFromContext para acceder a las claims desde handlers
- 401 claro si RBAC se usa sin JWT antes (code: no_claims)
2026-04-18 17:44:04 +02:00

43 lines
2.2 KiB
Markdown

---
name: jwt_middleware
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func JWTMiddleware(secret string) Middleware"
description: "Middleware HTTP que extrae el JWT del header Authorization: Bearer y valida con JWTValidate. Inyecta las claims en el context del request (recuperables con JWTClaimsFromContext). Responde 401 si falta el header, formato incorrecto o token invalido."
tags: [jwt, auth, middleware, http, server, infra]
uses_functions: [jwt_validate_go_infra, http_error_response_go_infra]
uses_types: [JWTClaims_go_infra, Middleware_go_infra, HTTPError_go_infra]
returns: [Middleware_go_infra]
returns_optional: false
error_type: error_go_core
imports: [context, net/http, strings]
params:
- name: secret
desc: "clave HMAC para JWTValidate. Debe ser la misma usada en JWTGenerate"
output: "Middleware que protege handlers con validacion JWT. Las claims se inyectan en r.Context() con una key privada"
tested: true
tests: ["pasa con token valido", "401 sin header Authorization", "401 con formato distinto de Bearer", "401 con token invalido", "claims accesibles via JWTClaimsFromContext"]
test_file_path: "functions/infra/jwt_middleware_test.go"
file_path: "functions/infra/jwt_middleware.go"
---
## Ejemplo
```go
protected := HTTPMiddlewareChain(
HTTPLoggerMiddleware(os.Stderr),
JWTMiddleware(os.Getenv("JWT_SECRET")),
)
mux.Handle("GET /api/me", protected(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
claims, _ := JWTClaimsFromContext(r.Context())
HTTPJSONResponse(w, 200, map[string]string{"user_id": claims.Subject})
})))
```
## Notas
Impura — lee headers y modifica el request. Expone el helper JWTClaimsFromContext(ctx) que devuelve (JWTClaims, bool) — el bool permite distinguir "no autenticado" de "subject vacio". Usa `context.WithValue` con una key de tipo privado `jwtCtxKey struct{}` para evitar colisiones con otros middlewares. Solo soporta cabecera `Authorization: Bearer`; para leer token desde cookie se crearia un middleware separado. En las respuestas 401 no se da detalle del motivo (token expirado vs firma invalida) para no filtrar informacion, el motivo real esta en los logs si se compone con HTTPLoggerMiddleware.