Skip to main content

Introduction

The Mueve API uses JWT (JSON Web Tokens) for secure authentication. All authenticated endpoints require a valid token to be included in the request headers.
JWT tokens provide a stateless authentication mechanism, allowing secure API access without storing session data on the server.

Authentication Flow

1

User Registration

Create a new account by providing name, email, and password. Passwords are hashed using bcrypt with a salt round of 10 before storage.
2

User Login

Authenticate with email and password. The API validates credentials and returns a JWT token if successful.
3

Access Protected Resources

Include the JWT token in the Authorization header of subsequent requests using the Bearer schema.
4

Token Validation

The server verifies the token on each request to protected endpoints. Invalid or expired tokens result in a 403 error.

Security Features

Password Hashing

All passwords are encrypted using bcrypt before being stored in the database. Bcrypt is a one-way hashing algorithm that provides strong protection against rainbow table attacks.
import bcrypt from "bcrypt";

// Hash password with salt rounds of 10
const hashedPassword = await bcrypt.hash(password, 10);

// Verify password during login
const isMatch = await bcrypt.compare(password, user.password);
Never store passwords in plain text. The Mueve API uses bcrypt with 10 salt rounds to ensure password security.

JWT Token Structure

JWT tokens generated by the API contain the following payload:
{
  "id": 123,
  "email": "[email protected]",
  "iat": 1234567890,
  "exp": 1234654290
}
id
integer
The unique user ID from the database
email
string
The user’s email address
iat
integer
Token issued at timestamp (Unix epoch)
exp
integer
Token expiration timestamp (Unix epoch)

Token Expiration

JWT tokens expire after 24 hours (1 day) from issuance. After expiration, users must log in again to obtain a new token.
The token expiration is set in the JWT signing process:
const token = jwt.sign(
  { id: user.id, email: user.email },
  process.env.JWT_SECRET,
  { expiresIn: "1d" } // 1 day expiration
);

Token Verification Middleware

Protected routes use the verifyToken middleware to validate authentication:
import jwt from "jsonwebtoken";

export const verifyToken = async (req, res, next) => {
  try {
    // Get Authorization header
    const authHeader = req.headers["authorization"];
    
    if (!authHeader) {
      return res.status(401).json({ message: "No se proporcionó token" });
    }
    
    // Extract token (format: "Bearer <token>")
    const token = authHeader.split(" ")[1];
    if (!token) {
      return res.status(401).json({ message: "Formato de token inválido" });
    }
    
    // Verify token with secret key
    const decoded = await jwt.verify(token, process.env.JWT_SECRET);
    
    // Store decoded user data in req.user
    req.user = decoded;
    
    // Continue to next middleware or controller
    next();
  } catch (error) {
    return res.status(403).json({ message: "Token inválido o expirado" });
  }
};

Using Authentication Headers

For all protected endpoints, include the JWT token in your request headers:
curl -X GET http://localhost:3001/api/protected-endpoint \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Error Responses

Returned when the Authorization header is missing.
{
  "message": "No se proporcionó token"
}
Returned when the token format is incorrect (not “Bearer <token>”).
{
  "message": "Formato de token inválido"
}
Returned when the token is invalid, expired, or tampered with.
{
  "message": "Token inválido o expirado"
}

Best Practices

Security Recommendations:
  • Store JWT tokens securely (use httpOnly cookies or secure storage)
  • Never expose tokens in URL parameters
  • Implement token refresh logic before expiration
  • Use HTTPS for all API communications
  • Rotate JWT_SECRET regularly in production

Next Steps

Register Users

Learn how to register new users

User Login

Authenticate and obtain JWT tokens

Build docs developers (and LLMs) love