Skip to main content

Authentication

MaqAgr API uses JSON Web Tokens (JWT) for secure authentication. All protected endpoints require a valid Bearer token in the request header.

Authentication Flow

The authentication process follows these steps:
1

User Registration or Login

Users authenticate via /api/auth/register or /api/auth/login endpoints.
2

Receive JWT Token

Upon successful authentication, the API returns a JWT token valid for 24 hours.
3

Include Token in Requests

Send the token in the Authorization header with the Bearer scheme for all protected endpoints.
4

Token Validation

The API validates the token on each request using the verifyTokenMiddleware.

Registration

Create a new user account to receive an authentication token.

Endpoint

POST /api/auth/register

Request Body

name
string
required
Full name of the user
email
string
required
Valid email address (must be unique)
password
string
required
Strong password meeting security requirements:
  • Minimum 8 characters
  • At least one uppercase letter
  • At least one lowercase letter
  • At least one number
  • At least one special character

Example Request

curl -X POST http://localhost:4000/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Juan Pérez",
    "email": "[email protected]",
    "password": "SecurePass123!"
  }'

Response (201 Created)

{
  "success": true,
  "message": "Usuario registrado exitosamente",
  "data": {
    "user": {
      "user_id": 1,
      "name": "Juan Pérez",
      "email": "[email protected]",
      "role_id": 2,
      "status": "active",
      "registration_date": "2026-03-11T10:00:00.000Z"
    },
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJlbWFpbCI6Imp1YW5AZXhhbXBsZS5jb20iLCJyb2xlX2lkIjoyLCJuYW1lIjoiSnVhbiBQw6lyZXoiLCJpYXQiOjE3MTAxNTEyMDAsImV4cCI6MTcxMDIzNzYwMH0..."
  }
}
New users are automatically assigned role_id: 2 (regular user). Only administrators can modify user roles.

Login

Authenticate with existing credentials to receive a new token.

Endpoint

POST /api/auth/login

Request Body

email
string
required
Registered email address
password
string
required
User’s password

Example Request

curl -X POST http://localhost:4000/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "SecurePass123!"
  }'

Response (200 OK)

{
  "success": true,
  "message": "Inicio de sesión exitoso",
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "user": {
      "name": "Juan Pérez",
      "email": "[email protected]",
      "role_id": 2
    }
  }
}
Successful login updates the user’s last_session field in the database to track activity.

JWT Token Structure

Token Format

JWT tokens consist of three Base64-encoded parts separated by dots:
header.payload.signature
Example:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxLCJlbWFpbCI6Imp1YW5AZXhhbXBsZS5jb20iLCJyb2xlX2lkIjoyLCJuYW1lIjoiSnVhbiBQw6lyZXoiLCJpYXQiOjE3MTAxNTEyMDAsImV4cCI6MTcxMDIzNzYwMH0.xyz123...

Token Payload

The decoded payload contains:
{
  "user_id": 1,
  "email": "[email protected]",
  "role_id": 2,
  "name": "Juan Pérez",
  "iat": 1710151200,
  "exp": 1710237600
}
user_id
integer
Unique user identifier
email
string
User’s email address (stored in lowercase)
role_id
integer
User role: 1 = Admin, 2 = Regular User
name
string
User’s full name
iat
integer
Issued at timestamp (Unix epoch)
exp
integer
Expiration timestamp (Unix epoch, 24 hours after iat)

Token Configuration

  • Algorithm: HS256 (HMAC with SHA-256)
  • Expiration: 24 hours (configurable via JWT_EXPIRES_IN env variable)
  • Secret: Defined in JWT_SECRET environment variable
Never use the default development secret ('clave_secreta_desarrollo') in production. Always set a strong, unique JWT_SECRET in your .env file.

Using Bearer Tokens

All protected endpoints require the token in the Authorization header using the Bearer scheme.

Header Format

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Example: Get User Profile

curl -X GET http://localhost:4000/api/auth/profile \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Response (200 OK)

{
  "success": true,
  "message": "Perfil obtenido exitosamente",
  "data": {
    "user": {
      "user_id": 1,
      "name": "Juan Pérez",
      "email": "[email protected]",
      "role_id": 2,
      "role_name": "Usuario",
      "status": "active",
      "registration_date": "2026-03-11T10:00:00.000Z",
      "last_session": "2026-03-11T10:05:00.000Z"
    }
  }
}

Token Validation Middleware

The API uses the verifyTokenMiddleware (defined in src/middleware/auth.middleware.js) to validate tokens:
export const verifyTokenMiddleware = (req, res, next) => {
  try {
    // Extract Authorization header
    const authHeader = req.headers['authorization'];
    
    if (!authHeader) {
      return res.status(401).json({
        success: false,
        message: 'Token no proporcionado'
      });
    }
    
    // Extract token (format: Bearer <token>)
    const token = authHeader.split(' ')[1];
    
    if (!token) {
      return res.status(401).json({
        success: false,
        message: 'Formato de token inválido'
      });
    }
    
    // Verify and decode token
    const decoded = verifyToken(token);
    
    // Attach user data to request
    req.user = decoded;
    
    next();
  } catch (error) {
    return res.status(401).json({
      success: false,
      message: 'Token inválido o expirado'
    });
  }
};
After successful validation, the decoded token payload is available in req.user for use in route handlers.

Protected Endpoints

The following endpoints require authentication:

Authentication Endpoints

MethodEndpointDescriptionAuth Required
POST/api/auth/registerRegister new userNo
POST/api/auth/loginLogin and get tokenNo
POST/api/auth/logoutLogout (stateless)Yes
GET/api/auth/profileGet user profileYes
PUT/api/auth/profileUpdate profileYes
PUT/api/auth/passwordChange passwordYes

Resource Endpoints

All endpoints under these paths require authentication:
  • /api/tractors - Tractor management
  • /api/implements - Implement management
  • /api/terrains - Terrain management
  • /api/calculations - Power calculations
  • /api/recommendations - Tractor recommendations
  • /api/admin - Admin operations (requires role_id: 1)

Role-Based Access Control

Some endpoints require specific roles:

Admin Middleware

The isAdmin middleware restricts access to administrators only:
export const isAdmin = (req, res, next) => {
  if (!req.user) {
    return res.status(401).json({
      success: false,
      message: 'No autenticado'
    });
  }
  
  if (req.user.role_id !== 1) {
    return res.status(403).json({
      success: false,
      message: 'Acceso denegado: se requiere rol de administrador'
    });
  }
  
  next();
};

Role IDs

  • role_id: 1 - Administrator (full access)
  • role_id: 2 - Regular User (standard access)
Admin-only endpoints include creating tractors (POST /api/tractors), managing users, and other administrative functions.

Error Responses

Missing Token

{
  "success": false,
  "message": "Token no proporcionado"
}
HTTP Status: 401 Unauthorized

Invalid Token Format

{
  "success": false,
  "message": "Formato de token inválido"
}
HTTP Status: 401 Unauthorized

Expired or Invalid Token

{
  "success": false,
  "message": "Token inválido o expirado"
}
HTTP Status: 401 Unauthorized
Tokens expire after 24 hours. When your token expires, simply log in again to receive a fresh token.

Insufficient Permissions

{
  "success": false,
  "message": "Acceso denegado: se requiere rol de administrador"
}
HTTP Status: 403 Forbidden

Invalid Credentials (Login)

{
  "success": false,
  "message": "Credenciales inválidas"
}
HTTP Status: 401 Unauthorized

Inactive User

{
  "success": false,
  "message": "Usuario inactivo o suspendido"
}
HTTP Status: 401 Unauthorized
Users with status other than 'active' cannot log in, even with correct credentials.

Rate Limiting

Authentication endpoints have rate limiting to prevent abuse:
  • Login endpoint (/api/auth/login): Stricter limits via loginLimiter
  • Register endpoint (/api/auth/register): Public limits via publicLimiter
  • Protected endpoints: General API limits via apiLimiter
Rate limit headers are included in responses:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 99
X-RateLimit-Reset: 1710151800

Security Best Practices

Use HTTPS

Always use HTTPS in production to encrypt tokens in transit

Secure Storage

Store tokens securely (e.g., httpOnly cookies, secure storage)

Token Expiration

Tokens expire after 24 hours - implement refresh logic in your client

Strong Secrets

Use a cryptographically strong JWT_SECRET (minimum 32 characters)

Password Hashing

Passwords are hashed with bcrypt (10 salt rounds) before storage

Input Sanitization

All inputs are sanitized via sanitizeInputs middleware (XSS protection)

Logout

Since JWT is stateless, logout is handled client-side.

Endpoint

POST /api/auth/logout

Example Request

curl -X POST http://localhost:4000/api/auth/logout \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Response (200 OK)

{
  "success": true,
  "message": "Sesión cerrada exitosamente",
  "data": null
}
The logout endpoint returns a confirmation message, but since JWT is stateless, you must delete the token on the client side to complete logout.

Password Management

Change Password

Authenticated users can change their password:
PUT /api/auth/password
Request Body:
{
  "currentPassword": "SecurePass123!",
  "newPassword": "NewSecurePass456!"
}
Response (200 OK):
{
  "success": true,
  "message": "Contraseña actualizada exitosamente",
  "data": null
}
The new password must meet the same security requirements as registration. The current password is verified before allowing the change.

Next Steps

API Reference

Explore all available API endpoints

Error Handling

Learn about error responses and handling

Rate Limiting

Understand API rate limits and quotas

Examples

View practical authentication examples

Build docs developers (and LLMs) love