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.
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.
Sign up to get a token, then use it to fetch your profile:
curl -X POST http://localhost:3000/api/auth/signup \ -H "Content-Type: application/json" \ -d '{"name": "Ada Lovelace", "email": "ada@example.com", "password": "securepassword"}'# Save the returned "token" value
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.
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.