Lightweight demo showing how to implement JWT-based authentication with Node.js, Express and MongoDB.
- Small, focused example for learning JWT auth flows: register, login, and a protected profile route.
- Uses bcrypt for secure password hashing and jsonwebtoken for token creation/verification.
- Node.js (16+ recommended)
- pnpm, npm or yarn (pnpm used for the lockfile here)
- A running MongoDB instance (local or hosted)
Create a .env
file in the project root with the following values:
PORT
(optional) - server port, default 5000MONGO_URI
- MongoDB connection stringJWT_SECRET
- secret string used to sign JWT tokens (keep this private)
Example .env
:
PORT=5000
MONGO_URI=mongodb://localhost:27017/jwt-demo
JWT_SECRET=your-super-secret-key
- Install dependencies:
pnpm install
# or `npm install` / `yarn install`
- Start the server in development mode (uses nodemon):
pnpm run dev
# or `npm run dev` if you use npm
- Server will be available at http://localhost:5000 (or your
PORT
).
server.js
— app entry pointroutes/auth.js
— register/login/profile routescontrollers/authController.js
— request handlersservices/hashService.js
— bcrypt helpersservices/jwtService.js
— token helpersmodels/User.js
— Mongoose user modelmiddlewares/authMiddleware.js
— protects routes by verifying JWT
Base path: /api/auth
- Register
- Endpoint: POST /api/auth/register
- Body (JSON): { name, email, password }
- Response: 201 on success
Example (curl):
curl -X POST http://localhost:5000/api/auth/register \
-H "Content-Type: application/json" \
-d '{"name":"Sumit Saha","email":"sumit@saha.com","password":"secret"}'
- Login
- Endpoint: POST /api/auth/login
- Body (JSON): { email, password }
- Response: { message, token }
Example (curl):
curl -X POST http://localhost:5000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"sumit@saha.com","password":"secret"}'
- Profile (protected)
- Endpoint: GET /api/auth/profile
- Requires
Authorization: Bearer <token>
header
Example (curl):
curl http://localhost:5000/api/auth/profile \
-H "Authorization: Bearer <TOKEN_FROM_LOGIN>"
- Use a strong, unpredictable
JWT_SECRET
and keep it out of source control. - In production, set token expiration and consider refresh tokens for long sessions.
- Hash passwords (already done with bcrypt here) and never return raw password fields in responses.
- Consider adding rate limiting and account lockout to mitigate brute-force attacks.
- You can test the endpoints with curl, httpie, Postman, or a small test script.
This demo is provided for educational purposes. Feel free to reuse and adapt.