Autenticación
Autenticación
NeoPOS usa JWT (HS256) con refresh token rotacional para la autenticación. Esto significa que cada vez que refrescas tu token, el anterior queda invalidado.
Flujo completo
- Login →
POST /api/auth/login→ obtienesaccess_token+refresh_token - Si
password_must_change=true→ los endpoints protegidos retornan403concode: "PASSWORD_CHANGE_REQUIRED"→ usaPATCH /api/auth/change-password - Re-login con la nueva contraseña
- Llamadas autenticadas → incluir
Authorization: Bearer <access_token> - Refrescar (cuando expire) →
POST /api/auth/refreshconrefresh_token - Logout →
POST /api/auth/logoutinvalida ambos tokens
Obtener tokens (Login)
curl -X POST https://api.neopos.app/api/auth/login \ -H "Content-Type: application/json" \ -d '{"correo": "soporte@neoapp.com", "password": "12345678"}'Respuesta exitosa:
{ "access_token": "eyJhbGciOiJIUzI1NiIs...", "refresh_token": "a1b2c3d4e5f6...", "token_type": "bearer", "expires_in": 3600, "usuario": { "id": 1, "nombre": "Soporte NeoApp", "correo": "soporte@neoapp.com", "rol": 3, "tenant_id": "uuid-tenant", "password_must_change": false }, "permisos": [], "tenant": {}, "password_must_change": false}Errores: 401 (credenciales inválidas), 403 con code: "PASSWORD_CHANGE_REQUIRED" (debe cambiar contraseña)
Refrescar tokens
Cuando el access_token expira (por defecto en 1 hora), usa el refresh_token para obtener uno nuevo. La rotación invalida el refresh anterior.
curl -X POST https://api.neopos.app/api/auth/refresh \ -H "Content-Type: application/json" \ -d '{"refresh_token": "a1b2c3d4e5f6..."}'Respuesta: misma estructura que login (nuevo access_token + nuevo refresh_token)
Cerrar sesión (Logout)
Invalida ambos tokens activos:
curl -X POST https://api.neopos.app/api/auth/logout \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <access_token>" \ -d '{"refresh_token": "a1b2c3d4e5f6...", "access_token": "eyJ..."}'Manejo de expiración
| Token | Duración | Qué pasa al expirar |
|---|---|---|
access_token | 1 hora | Las llamadas devuelven 401 — haz refresh |
refresh_token | 7 días | Debes hacer login nuevamente |
Recomendación: Refresca el token cuando recibas un 401 o antes de que expire (ej. cada 30 minutos en segundo plano).
Rotación de refresh tokens
Cada vez que llamas a /api/auth/refresh, el refresh token anterior se invalida automáticamente. Esto previene ataques de reutilización. Si un atacante roba un refresh token, solo será válido hasta el próximo refresh legítimo.
Verificar token
curl https://api.neopos.app/api/auth/verify \ -H "Authorization: Bearer <access_token>"Respuesta: información del payload JWT, tiempo restante, estado de expiración.
Cambio de contraseña obligatorio (password_must_change)
Cuando un usuario se registra o se crea mediante register-tenant, el flag password_must_change se establece en true. Esto fuerza al usuario a cambiar su contraseña en el primer inicio de sesión.
Flujo:
POST /api/auth/login→ respuesta incluyepassword_must_change: true- Cualquier endpoint protegido retorna
403con{ "code": "PASSWORD_CHANGE_REQUIRED", "message": "..." } - El usuario llama a
PATCH /api/auth/change-password(funciona incluso con el flag activo):Terminal window curl -X PATCH https://api.neopos.app/api/auth/change-password \-H "Content-Type: application/json" \-H "Authorization: Bearer <access_token>" \-d '{"old_password": "Passw0rd!", "new_password": "NewPass1@"}' - El flag se limpia y el usuario debe hacer login nuevamente
La nueva contraseña debe cumplir: mínimo 8 caracteres, al menos una mayúscula, un número y un carácter especial.
Referencia de endpoints
Para la lista completa de endpoints de autenticación, consulta la referencia de Auth.