El token que se guarda en claro y no caduca, el JWT que consulta la base de datos igual que él, y la palabra que hay que escribir para que te dejen entrar.
⏱ 17 min de lectura
La lección 7 vio la autenticación desde el lado de quien consume una API. Ahora toca escribirla, y DRF trae dos caminos: su sistema de tokens, que viene incluido, y JWT, que necesita un paquete.
El argumento habitual para elegir entre los dos es que el JWT no consulta la base de datos. Medido aquí, los dos consultan.
Usuario y contraseña en cada petición. Para pruebas
TokenAuthentication
Un token por usuario en la base de datos
RemoteUserAuthentication
Cuando autentica un servidor delante
El orden importa: DRF prueba una tras otra y se queda con la primera que devuelva un usuario. Y si ninguna lo hace, el usuario es anónimo y decide el permiso.
Un detalle que hay que conocer: la de sesión comprueba el CSRF. Es correcto —una cookie viaja sola y hay que protegerla, que es la lección 42 del módulo 4— y es la causa del 403 misterioso al probar desde el navegador estando identificado. La de token no lo comprueba, porque una cabecera no la manda el navegador por su cuenta.
Uno por usuario. El usuario es único en la tabla, así que una persona no puede tener un token para el móvil y otro para un guion. Cerrar sesión en un sitio la cierra en todos.
No caduca. No hay campo de caducidad ni comprobación. Un token emitido hoy vale dentro de cinco años.
Se guarda en claro:
Salida en pantalla
en la base de datos: ('6cda1889e2aac40d35697a4c944f66c1bd9ffabc', 1)
Ahí está la clave tal cual. Django se toma muchas molestias en guardar las contraseñas con resumen —la lección 32 del módulo 4— y luego guarda estos tokens sin ninguna, aunque den el mismo acceso.
Quien consiga una copia de la base de datos tiene todas las cuentas, sin romper nada. Una copia de seguridad mal guardada, un volcado para depurar, un desarrollador con acceso de lectura: cualquiera de esas cosas es suficiente.
Lo que esto significa en la práctica:
Vale para APIs internas, guiones de la casa, integraciones entre servicios tuyos. Es simple y funciona.
No vale para una aplicación con usuarios reales. Ahí hacen falta tokens que caduquen, que se revoquen y que no estén en claro.
Y hay paquetes que lo arreglan: django-rest-knox da varios tokens por usuario, con caducidad y guardados con resumen, manteniendo la simplicidad.
POST /api/token/ {"username": "ana", "password": "clave-larga-123"}
200 {"access": "...", "refresh": "..."}
longitud del de acceso: 231 caracteres
cabecera: {"alg": "HS256", "typ": "JWT"}
carga: {"token_type": "access", "exp": 1790105720, "iat": 1790105420,
"jti": "7926d06f23d241cdb608c9c5934fe6b5", "user_id": "1"}
el de acceso vive 5 minutos
el de refresco vive 1 día
Cinco minutos de fábrica, que es conservador y correcto. Y fíjate en el jti, un identificador único del token: es lo que permite anotarlo en una lista negra, que es lo único que hace revocable un JWT.
Si tu API la consume tu propio sitio web, en el mismo dominio, la sesión es la respuesta y no hace falta nada más. Es lo que menos código tiene y lo más seguro, porque la cookie puede ser HttpOnly y el JavaScript de la página no puede leerla.
Si es una aplicación móvil o un cliente ajeno, tokens. Y entonces JWT si quieres caducidad y refresco, o Knox si quieres lo mismo con revocación instantánea.
Si tienes varios servicios que tienen que verificar quién eres sin compartir base de datos, JWT es la única de las tres que sirve.
Si es una API interna entre programas tuyos, el token de DRF basta, guardado en el entorno.