Authenticate with your credentials to receive a JWT token that grants access to protected API endpoints.
Login Endpoint
Required Fields
Field Type Validation Description emailstring Valid email format Registered user email passwordstring Minimum 8 characters User password
Example Request
curl -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected] ",
"password": "securePassword123"
}'
Success Response
When authentication succeeds, you receive a JWT token:
{
"message" : "Inicio de sesión exitoso" ,
"token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IlBBVElFTlQiLCJpYXQiOjE3MDk1NjQ4MDAsImV4cCI6MTcwOTU2ODQwMH0.example_signature"
}
Status Code : 200 OK
The token in the response is a complete JWT that you must include in the Authorization header for subsequent API requests.
Login Process Flow
The authentication flow (src/services/authService.js:34-47) works as follows:
Find User
The system looks up the user by email in the database.
Verify Password
Uses bcrypt to compare the provided password with the stored hash.
Generate Token
Creates a JWT token containing user ID and role, valid for 1 hour.
Log Audit
Records the login event in the audit log.
Return Token
Sends the token to the client for use in future requests.
Using the Token
Once you have the token, include it in the Authorization header using the Bearer scheme:
curl http://localhost:3000/api/users/me \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
The token format is Bearer <token>. Make sure to include the word “Bearer” followed by a space before the actual token.
Token Payload
The JWT token contains the following claims:
// From src/services/authService.js:40-44
const token = jwt . sign (
{ id: user . id , role: user . role },
process . env . JWT_SECRET ,
{ expiresIn: '1h' }
);
Claim Description idUser’s unique identifier roleUser’s role (PATIENT, DOCTOR, or ADMIN) iatIssued at timestamp expExpiration timestamp (1 hour from issue)
Error Responses
Invalid Credentials
When email or password is incorrect:
Status Code : 401 Unauthorized
{
"error" : "Usuario y/o contraseña incorrecta"
}
The error message is intentionally generic to prevent user enumeration attacks. You cannot determine whether the email or password was incorrect.
Missing Fields
When required fields are not provided:
Status Code : 401 Unauthorized
{
"error" : "Usuario y/o contraseña incorrecta"
}
Status Code : 400 Bad Request
{
"error" : " \" email \" must be a valid email"
}
Complete Example: Login and Access Protected Resource
Here’s a complete workflow showing login and accessing a protected endpoint:
# Step 1: Login
TOKEN = $( curl -s -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected] ",
"password": "securePassword123"
}' | jq -r '.token' )
echo "Token: $TOKEN "
# Step 2: Access protected route
curl http://localhost:3000/api/auth/protected-route \
-H "Authorization: Bearer $TOKEN "
Security Implementation
Password Comparison
The system uses bcrypt’s secure comparison to prevent timing attacks:
// From src/services/authService.js:35-36
const user = await prisma . user . findUnique ({ where: { email } });
const isPasswordValid = user ? await bcrypt . compare ( password , user . password ) : false ;
Constant-Time Response
The system performs password comparison even if the user doesn’t exist, preventing attackers from determining valid email addresses through timing analysis.
Audit Logging
Every successful login is recorded in the audit log with the user ID and action type (login).
Token Expiration
Tokens expire after 1 hour . When a token expires, you will receive a 403 Forbidden error and must login again.
The API does not currently support token refresh. You must re-authenticate to obtain a new token.
Next Steps
JWT Token Details Learn about token structure, validation, and error handling
Protected Endpoints Explore API endpoints that require authentication