A secure backend authentication system built with Node.js, Express, and MongoDB. Uses JWT access & refresh tokens with role-based access control.
- User Registration & Login
- JWT Access Tokens (15 min) & Refresh Tokens (7 days)
- Refresh Token Rotation with httpOnly Cookies
- Role-Based Access Control (User, Admin, Moderator)
- Password Hashing (bcrypt)
- Rate Limiting
- Input Validation
- Logout / Logout All Devices
- Node.js
- Express.js
- MongoDB + Mongoose
- JSON Web Tokens (JWT)
- bcryptjs
- Joi
- cookie-parser
- express-rate-limit
Authentication
├── config/db.js
├── controllers/authController.js
├── middleware/
│ ├── authMiddleware.js
│ ├── roleMiddleware.js
│ └── rateLimiter.js
├── models/
│ ├── User.js
│ └── RefreshToken.js
├── routes/
│ ├── authRoutes.js
│ └── protectedRoutes.js
├── utils/
│ ├── generateTokens.js
│ └── validateInput.js
├── server.js
├── .env
└── package.json
- User sends POST /api/auth/register with { username, email, password }
- Rate Limiter checks — if more than 10 requests in 15 min → 429 blocked
- Joi Validator checks input:
- Username: minimum 3 characters, maximum 30 characters, required
- Email: must be valid format, required
- Password: minimum 8 characters, must have uppercase + lowercase + number
- If any validation fails → 400 error with specific message
- Database check — does a user with this email or username already exist?
- If yes → 409: User already exists
- Create user in MongoDB
- Before saving, the pre-save hook runs automatically
- bcrypt generates a salt (12 rounds)
- bcrypt hashes the plain password → "$2a$12$xK9f..."
- Only the hash is stored, never the plain password
- Generate Access Token (JWT)
- Contains: userId, email, role
- Signed with ACCESS_TOKEN_SECRET
- Expires in: 15 minutes
- Generate Refresh Token (JWT)
- Contains: userId only
- Signed with REFRESH_TOKEN_SECRET
- Expires in: 7 days
- Saved to MongoDB (RefreshTokens collection)
- Set refresh token as httpOnly cookie
- httpOnly: true → JavaScript can't access it
- secure: true in production → only sent over HTTPS
- sameSite: strict → prevents CSRF attacks
- Send response → 201 Created
- Body: { accessToken, user: { id, username, email, role } }
- Cookie: refreshToken (set automatically)
- PORT -> Your server will run on localhost:5000
- MONGODB_URI -> Address of your MongoDB database
- ACCESS_TOKEN_SECRET -> Secret key to sign access tokens (like a stamp of authenticity)
- REFRESH_TOKEN_SECRET -> Secret key to sign refresh tokens (separate for extra security)
- ACCESS_TOKEN_EXPIRY -> Access token dies after 15 minutes
- REFRESH_TOKEN_EXPIRY -> Refresh token dies after 7 days
- CLIENT_URL -> Your frontend's address (for CORS)
- NODE_ENV -> Tells the app if it's in development or production mode
git clone https://github.com/your-username/Authentication_System_Backend.git
npm install
Kaushiki Tripathi