Skip to main content
Mais Hábito uses JWT (JSON Web Tokens) for stateless authentication and bcrypt for password hashing. After signing up or logging in, you receive a token that must be included in every subsequent request to a protected endpoint.

How it works

  1. The client sends credentials (email + password) to /api/auth/signup or /api/auth/login.
  2. The server hashes the password with bcrypt (10 salt rounds) and verifies it against the stored hash.
  3. On success, the server signs a JWT containing userId, email, and name, with a 30-day expiry.
  4. The client stores the token and sends it as a Bearer token in the Authorization header on every subsequent request.
  5. authMiddleware intercepts incoming requests, splits the Bearer <token> string, and calls authService.validateToken() to verify the signature and expiry.
  6. If valid, req.user is populated with the decoded payload and the request proceeds to the controller.

Signup

POST /api/auth/signup Create a new account. Returns a token immediately — no separate login step required.

Request body

Example

Response — 201 Created

Login

POST /api/auth/login Authenticate an existing user. Returns a fresh token.

Request body

Example

Response — 200 OK

Using the token

Include the token in the Authorization header for every protected request:

End-to-end example

Sign up to get a token, then use it to fetch your profile:

Protected vs public endpoints

Only the two auth routes are public. Every other endpoint requires a valid Bearer token:

The auth middleware

authMiddleware (defined in src/middlewares/auth.ts) runs on every protected route. It reads the Authorization header, splits the Bearer <token> string, and calls authService.validateToken() to verify the JWT signature and expiry. If validation passes, it attaches { userId, email, name } to req.user so controllers can access the authenticated user’s identity without querying the database again.

Error responses

Security notes

Never store your JWT token in localStorage in a browser environment — it is vulnerable to XSS attacks. Prefer httpOnly cookies or a secure in-memory store. On the server side, keep your JWT_SECRET environment variable long, random, and never committed to source control.
Tokens expire after 30 days. After expiry, the client must log in again to obtain a new token. There is currently no token refresh endpoint — a new token is issued on each login.