Seguridad
Autenticación con JWT (JSON Web Tokens) — registro de usuarios, inicio de sesión y gestión de perfiles.
La autenticación usa el algoritmo HS512 con la librería
python-jose.
Los tokens tienen una expiración de 24 horas y deben enviarse en el header
Authorization de cada petición protegida.
3
Endpoints
2
Roles (admin / profesor)
Modelo de Datos
Perfil
tabla: perfil (extiende auth_user)
El modelo
Perfil extiende el modelo User de Django con un
OneToOneField. Al crearse un usuario se crea automáticamente su perfil asociado.
| Campo | Tipo | Constraint | Descripción |
|---|---|---|---|
| id | integer | auto | Clave primaria autoincremental. |
| user | OneToOne → User | requerido | Relación uno-a-uno con el usuario de Django. Se elimina en cascada. |
| cargo | string(255) | opcional | Cargo o puesto del usuario en la institución. Predeterminado: "". |
| permissions | string(255) | requerido |
Nivel de permisos del usuario. Valores posibles:
admin (acceso total, puede eliminar registros) o
profesor (CRUD sin eliminación).
Predeterminado: "profesor".
|
Endpoints
POST
/api/v1/seguridad/reg
Registrar un nuevo usuario
🌐 público
▶
Crea un nuevo usuario en el sistema junto con su perfil asociado.
El campo
permissions determina el nivel de acceso del usuario.
Cuerpo de la petición (JSON)
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| username | string | requerido | Nombre de usuario único para el login. |
| string (email) | requerido | Correo electrónico del usuario. | |
| password | string | requerido | Contraseña del usuario (se almacena hasheada con make_password). |
| cargo | string | opcional | Cargo o puesto (máx. 255 caracteres). |
| permissions | string | opcional | Nivel de permisos: admin o profesor. Predeterminado: profesor. |
Ejemplo de petición
Request Body
{ "username": "jperez", "email": "jperez@universidad.edu", "password": "MiClave123", "cargo": "Técnico de Laboratorio", "permissions": "admin" }
Respuestas
201 Created
400 Bad Request
201 Created
{ "message": "Usuario creado exitosamente" }
400 Bad Request
{ "error": "correo electrónico ya existe" }
POST
/api/v1/seguridad/login
Iniciar sesión y obtener token JWT
🌐 público
▶
Valida las credenciales y retorna un token JWT que debe usarse en todas las peticiones autenticadas.
El token incluye el
user_id en su payload y expira en 24 horas.
Cuerpo de la petición (JSON)
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| string (email) | requerido | Correo electrónico del usuario. | |
| password | string | requerido | Contraseña del usuario. |
Ejemplo de petición
Request Body
{ "email": "jperez@universidad.edu", "password": "MiClave123" }
Respuestas
200 OK
401 Unauthorized
200 OK
{ "id": 1, "username": "jperez", "token": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9...", "role": "admin" }
401 Unauthorized
{ "error": "credenciales inválidas" }
Uso del token: El token retornado debe incluirse en el header de cada petición protegida:
Header de autorización
Authorization: Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9...
Nota: El token debe enviarse con el prefijo Bearer, por ejemplo: Bearer eyJhbGci...
GET
/api/v1/seguridad/perfil
Obtener el perfil del usuario autenticado
🔒 login
▶
No recibe parámetros de ruta. El usuario se identifica automáticamente
a partir del
user_id contenido en el token JWT enviado en el header Authorization.
Respuestas
200 OK
401 Unauthorized
200 OK
{ "user": 1, "user_name": "jperez", "mail": "jperez@universidad.edu", "cargo": "Técnico de Laboratorio", "permissions": "admin" }
Decoradores de Autorización
Funciones decoradoras que protegen las vistas verificando el token JWT y los permisos del usuario.
Decoradores disponibles
| Decorador | Acceso | Descripción |
|---|---|---|
| @logguer_required | 🔒 login |
Verifica que exista un token JWT válido en el header Authorization.
Decodifica el token y adjunta request.user_id al request.
Si el token no existe, está expirado o es inválido, retorna 401.
|
| @admin_required | 🛡️ admin |
Extiende @logguer_required: además de validar el token, verifica que
perfil.permissions == "admin". Si no es admin, retorna 403 Forbidden.
Se usa en todos los endpoints DELETE.
|
Respuestas de error de autorización:
401 Unauthorized — Token faltante, expirado o inválido
{ "status": "error", "message": "Token no proporcionado" }
403 Forbidden — Permisos insuficientes
{ "status": "error", "message": "Permisos insuficientes" }