Ir al contenido

Autenticación y permisos

Router: backend/app/api/v1/auth.py.

Credenciales de usuario. Devuelve tokens JWT.

{
"email": "admin@serconsa.com",
"password": "admin123"
}

Respuesta:

{
"access_token": "eyJhbG...",
"refresh_token": "eyJhbG...",
"token_type": "bearer"
}

Renueva el access token a partir del refresh token.

{
"refresh_token": "eyJhbG..."
}

Invalida el access token actual y el refresh token. Usa Redis blacklist.

Listado de auditoría de logins. Requiere admin:auditar.

  • Algoritmo: HS256.
  • Access token: duración configurable (ACCESS_TOKEN_EXPIRE_MINUTES).
  • Refresh token: 7 días por defecto.
  • Hash de contraseñas: bcrypt.
  • Blacklist de tokens y revocación masiva por usuario en Redis.

Implementación en backend/app/core/security.py.

Router: backend/app/api/v1/users.py.

Método Endpoint Descripción Permiso
GET /api/v1/users/me Usuario actual Autenticado
GET /api/v1/users Listar usuarios usuarios:leer
PUT /api/v1/users/{id} Actualizar usuario usuarios:editar
DELETE /api/v1/users/{id} Desactivar usuario usuarios:eliminar
PUT /api/v1/users/{id}/roles Asignar rol usuarios:editar
DELETE /api/v1/users/{id}/roles/{role_id} Quitar rol usuarios:editar

Modelo: backend/app/models/user.py.

Router: backend/app/api/v1/roles.py.

Modelos:

  • Role: backend/app/models/role.py.
  • Permission: backend/app/models/permission.py.
  • UserRole: relación usuario-rol.
Método Endpoint Descripción Permiso
GET /api/v1/roles Listar roles roles:leer
GET /api/v1/roles/{id} Detalle de rol roles:leer
POST /api/v1/roles Crear rol roles:crear
PUT /api/v1/roles/{id} Editar rol roles:editar
DELETE /api/v1/roles/{id} Borrar rol roles:eliminar
GET /api/v1/roles/{id}/permissions Permisos del rol roles:leer
POST /api/v1/roles/{id}/permissions Añadir permiso roles:editar
DELETE /api/v1/roles/{id}/permissions/{perm_id} Quitar permiso roles:editar

Un permiso se define por:

  • modulo: área funcional (budgets, certifications, usuarios, etc.).
  • accion: leer, crear, editar, eliminar, validar, auditar.
  • submenu y view: opcionales, para permisos más granulares.

El frontend guarda los tokens en localStorage y los adjunta en cada petición mediante un interceptor de axios (frontend/src/api/client.ts:17). Si recibe un 401, intenta refrescar el token; si falla, redirige a /login.

api.interceptors.request.use((config) => {
const { accessToken } = useAuthStore.getState();
if (accessToken) {
config.headers.Authorization = `Bearer ${accessToken}`;
}
return config;
});