pip install djangorestframework-simplejwt. No mires solutions.md hasta entregar.
Ejercicio 1 — Login con tokens
- Configura SimpleJWT (access 10 min, refresh 7 días, rotación + blacklist) y los endpoints de token. Haz login con tu usuario de prueba y anota los dos tokens.
- Llama a
GET /api/reservations/conAuthorization: Bearer <access>: 200. Sin header: 401. Con token expirado (espera o ajusta el lifetime a 5s): 401 contoken_not_valid. - Refresh: obtén un nuevo access y verifica que el refresh viejo ya no sirve (blacklist tras rotación).
Ejercicio 2 — Mira dentro del JWT
- Copia tu access token en jwt.io (o
base64 -dpor partes): ¿qué claims ves? ¿Está tu email? ¿Podría ir tu número de tarjeta? - Cambia un carácter del payload y usa el token: ¿qué error exacto? (firma inválida).
- Pregunta: ¿qué pasaría si el payload llevara el rol y alguien lo editara? (sin la firma no puede — explica el mecanismo).
Ejercicio 3 — Dónde vive el token
- Sirve una mini-página de prueba que haga fetch a tu API con el access en localStorage vs en cookie
HttpOnly; SameSite=Lax. Inyecta un "XSS" simulado (scriptque lee storage/document.cookie): ¿qué puede robar en cada caso? - Configura
CSRF_TRUSTED_ORIGINSy prueba el flujo con cookie + SameSite=Lax desde un "origen malo" (curl con Origin falso): ¿pasa el CSRF de Django? - Escribe el resumen de 3 líneas para tu README: dónde vive qué token en TicketFlow y por qué.
Ejercicio 4 — El ADR-0008
Escribe el ADR "Autenticación: JWT corto + refresh rotado en cookie HttpOnly" — contexto (web + móvil, revocación de compras), decisión, alternativas descartadas (solo sesión, JWT largo en localStorage), consecuencias (blacklist en Redis/BD, logout = blacklist del refresh, móviles con keychain).
Ejercicio 5 — Logout que funciona de verdad
- Implementa
POST /api/auth/logout/autenticado: blacklist del refresh del usuario. Verifica: tras logout, el refresh ya no da access. - ¿Y el access ya emitido (válido hasta 10 min)? ¿Es aceptable? ¿Cómo lo cortarías si no (pista: blacklist por jti con check en cada request — y qué pagas)?
Entrega
Pega configuración, tokens (recortados: ¡no el real!) y conclusiones. Después: Lección 19 — OAuth2 y OIDC.