Skip to main content
The API uses JSON Web Tokens (JWT) to protect user-specific resources. A token is issued when a user registers or logs in, and must be included as a token header on every request that touches private data — such as the cart or order endpoints. Requests that omit a valid token are rejected before they reach the route handler.

How authentication works

1

User registers or logs in

Calling POST /api/user/register or POST /api/user/login with valid credentials returns a signed JWT. The token payload contains the user’s MongoDB _id encoded under the id key.
2

Client stores the token

The React frontend persists the token in localStorage under the key "token". On page load, StoreContext reads it back and re-attaches it to every subsequent API call automatically.
frontend/src/context/StoreContext.jsx
3

Protected endpoints verify the token

Every protected route passes the request through authMiddleware before the controller runs. The middleware reads req.headers.token, verifies it against JWT_SECRET, and injects userId into req.body so controllers can use it directly.
backend/middleware/auth.js

Register a new user

This endpoint is public — no token is required.
POST /api/user/register Creates a new user account, validates the supplied data, hashes the password with bcrypt, persists the record to MongoDB, and returns a signed JWT on success.

Request body

string
required
The user’s display name. Stored as-is in the user collection.
string
required
A valid email address. Validated with the validator library — malformed addresses are rejected before the record is created. Must be unique across all accounts.
string
required
Plain-text password. Must be at least 8 characters. Hashed with bcrypt at salt-rounds 10 before being stored — the raw password is never persisted.

Responses

boolean
true when the account was created and a token was issued.
string
Signed JWT — present only on a successful response.
Success
Failure — email already registered
Failure — invalid email format
Failure — password too short

Example


Login

This endpoint is public — no token is required.
POST /api/user/login Looks up the user by email, compares the supplied password against the stored bcrypt hash, and returns a signed JWT on success.

Request body

string
required
The email address used when the account was created.
string
required
The account password in plain text. It is compared against the stored hash using bcrypt.compare — never logged or stored.

Responses

boolean
true when credentials matched and a token was issued.
string
Signed JWT — present only on a successful response.
Success
Failure — no account with that email
Failure — wrong password

Example


Using the token

Pass the JWT returned from register or login as a token HTTP header on every protected request. The middleware decodes it and automatically injects the userId into the request — you do not need to include userId in the request body yourself.
The React frontend passes the header the same way via Axios:
frontend/src/context/StoreContext.jsx
The header name is token (lowercase), not Authorization. Sending Authorization: Bearer <token> will not work — the middleware explicitly destructures req.headers.token and will respond with "Not Authorized Login Again" if it is absent.
Tokens are created with jwt.sign({id}, process.env.JWT_SECRET) and no expiresIn option is set, so tokens are valid indefinitely. They only become invalid if the JWT_SECRET environment variable changes on the server.

Protected endpoints

The following endpoints require a valid token header. Requests without one — or with a token signed by a different secret — are rejected by authMiddleware before reaching the controller.
Admin-only endpoints (GET /api/order/list, POST /api/order/status) and food listing (GET /api/food/list) are public and do not require a token.