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
- The client sends credentials (email + password) to
/api/auth/signup or /api/auth/login.
- The server hashes the password with bcrypt (10 salt rounds) and verifies it against the stored hash.
- On success, the server signs a JWT containing
userId, email, and name, with a 30-day expiry.
- The client stores the token and sends it as a
Bearer token in the Authorization header on every subsequent request.
authMiddleware intercepts incoming requests, splits the Bearer <token> string, and calls authService.validateToken() to verify the signature and expiry.
- 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.