auth-demo

By (author)Qasim Khan

Tech stack:
JS
Node.js
Express
MongoDB

l build a secure JWT authentication API using Node.js, Express, and MongoDB with access/refresh tokens, token rotation, RBAC, password security, rate ...
read more
AI Contributions:0
Published At:August 13, 2026
Files Included:19 file(s)
Updated At:October 22, 2026

Read Me

# auth-demo A hardened JWT authentication API built on Express + MongoDB/Mongoose. This is an upgraded version of a basic single-token auth demo, with the pieces you'd actually want before shipping something like this: - **Access + refresh token pair** instead of one long-lived JWT - Short-lived access token (15m default) returned in the response body, meant to be kept in memory on the client - Refresh token (7d default) stored as an `httpOnly`, `SameSite=Strict` cookie scoped to `/api/auth`, so client-side JS can never read it - **Refresh token rotation + reuse detection** — every `/refresh` call issues a brand new refresh token and revokes the old one. If a previously-rotated or revoked token is ever presented again (a strong signal of theft), every token for that user is revoked immediately. - **Password change invalidates existing sessions** — access tokens carry a `pwdChangedAt` claim checked against the user's real `passwordChangedAt`, and refresh tokens are revoked on password change. - **Account lockout** after 5 failed logins, 15 minute cooldown. - **Role-based access control** (`authorize("admin")` middleware) with an example `/api/auth/admin-only` route. - **Rate limiting** on register/login/refresh (`express-rate-limit`). - **Hardened HTTP headers** via `helmet`. - **CORS locked to an explicit origin allowlist** (`CORS_ORIGINS`), with `credentials: true` so the refresh cookie is actually sent cross-origin by browsers that need it. - **Input validation** via `express-validator` (email format, password complexity) instead of hand-rolled regex checks. - **Startup environment validation** — the server refuses to boot with missing or duplicate JWT secrets instead of failing confusingly later. - **Request logging** via `morgan`. ## Getting started ```bash npm install cp .env.example .env # then fill in real secrets npm run dev # nodemon # or npm start ``` Requires a running MongoDB instance reachable at `MONGODB_URI`. ## Environment variables See `.env.example`. The two JWT secrets **must** be different, long, random strings — the server will refuse to start otherwise. ## API All endpoints are under `/api/auth`. | Method | Path | Auth required | Description | |--------|-------------------|----------------|---------------------------------------------------| | POST | `/register` | no | Create an account, returns access token + sets refresh cookie | | POST | `/login` | no | Authenticate, returns access token + sets refresh cookie | | POST | `/refresh` | refresh cookie | Rotates the refresh token, returns a new access token | | POST | `/logout` | refresh cookie | Revokes the current refresh token, clears cookie | | POST | `/logout-all` | access token | Revokes every refresh token for the user (all devices) | | GET | `/me` | access token | Returns the current user | | PATCH | `/change-password`| access token | Changes password, revokes all existing sessions | | GET | `/admin-only` | access token, `admin` role | Example RBAC-gated route | Send the access token as `Authorization: Bearer `. The refresh token is handled automatically via cookie — just make sure your client sends requests `credentials: "include"`. ### Example flow ```bash # Register (cookie jar keeps the refresh token) curl -c cookies.txt -X POST http://localhost:5000/api/auth/register \ -H "Content-Type: application/json" \ -d '{"name":"Ada Lovelace","email":"ada@example.com","password":"Str0ngPass1"}' # Use the access token from the response curl http://localhost:5000/api/auth/me \ -H "Authorization: Bearer " # When the access token expires, get a new one curl -b cookies.txt -c cookies.txt -X POST http://localhost:5000/api/auth/refresh # Log out (revokes the refresh token) curl -b cookies.txt -X POST http://localhost:5000/api/auth/logout ``` ## What's intentionally still out of scope This is still a demo, not a full identity system. Not included: email verification, password-reset-via-email flow, OAuth/social login, MFA, and a persistent audit log of login attempts. The pieces above (token model, lockout, RBAC middleware) are built so any of those would slot in cleanly.

Loading

Loading

Loading

More like this View all

Idempotency Key Middleware for Express APIs

Express middleware that stops duplicate charges and orders from client retries. Send an Idempotency-Key header and repeated requests replay the original response instead of running twice.

  • 0

    Ratings

  • 2

    Files

    • JS
    • MongoDB
    • +3

    Tech stack

Webhook Delivery & Retry Engine with HMAC Signing

Reliable outbound webhook delivery for Node/Express apps: HMAC signing, automatic retries with backoff, and a dead-letter queue for failed deliveries.

  • 0

    Ratings

  • 2

    Files

    • JS
    • Node.js
    • +3

    Tech stack

Document Management System (DMS)

Managing digital assets efficiently is critical for modern applications. This Document Management System (DMS) provides a robust backend architecture built with Node.js and MongoDB

  • 0

    Ratings

  • 1

    Files

    • MongoDB
    • Node.js
    • +2

    Tech stack