A comprehensive, production-ready authentication system built with Node.js, Express, MongoDB, and JWT providing secure user management, session tracking, and role-based authorization.
- Features
- Implemented Functionality Checklist
- Tech Stack
- Security Implementation
- Project Structure
- API Endpoints
- Installation & Setup
- Usage Examples
- Environment Variables
- Data Models
- Future Enhancements
- Contributing
- License
- Acknowledgements
- Support
- Authors
-
User Authentication
- Secure registration with email verification
- Login with JWT tokens (access and refresh tokens)
- Hashed passwords with bcrypt
- Centralized environment configuration with validation
- Token rotation for enhanced security
-
Multi-Device Session Management
- Device tracking and limiting (configurable max devices)
- Active sessions viewing and management
- Single device logout
- Logout from all devices except current
- Device and IP tracking for enhanced security
-
Authorization
- Role-based access control (admin/user)
- Protected routes with middleware
- Token blacklisting for secure logout
-
Password Management
- Forgot password functionality
- Secure password reset with expiring tokens
- Strong password validation with express-validator
-
Security Measures
- Rate limiting to prevent brute force attacks
- Input validation to prevent injection attacks
- HTTP-only, secure, SameSite cookies
- Security headers with Helmet
- Token blacklisting system
- CORS protection with cors
- Environment variable validation at startup
- User registration with strong validation
- Email verification with secure tokens
- User login with JWT (access and refresh tokens)
- Password hashing with bcrypt (10 salt rounds)
- HTTP-only, secure cookies for token storage
- Session tracking and management
- Multi-device support with device limiting
- Role-based authorization (user/admin)
- Protected routes with middleware
- Refresh token rotation for enhanced security
- Token blacklisting for secure logout
- Centralized configuration with validation
- Environment variable validation at startup
- Time string parsing for token expiration
- Input validation with express-validator
- Rate limiting for API and login endpoints
- Forgot password functionality
- Password reset with expiring tokens
- Multi-device logout options
- Individual session termination
- Health check endpoint
- Security headers with Helmet
- User-Agent and IP tracking
- MongoDB TTL indexes for auto-cleanup
- Structured API responses with utils
- Backend Framework: Node.js + Express.js
- Database: MongoDB with (Mongoose ODM)
- Authentication: JWT with access and refresh tokens
- Password Hashing: bcrypt with 10 salt rounds
- Input Validation: express-validator
- Rate Limiting: express-rate-limit
- Security Headers: Helmet
- Cookie Handling: cookie-parser
- CORS Protection: cors
- Email Services: nodemailer with Mailtrap
- Environment Variables: dotenv
- Configuration Management: Centralized config with validation
This authentication system is designed with security in mind. Here are some of the security measures implemented:
-
Advanced Token System
- Short-lived access tokens (5 minutes) for API requests.
- Long-lived refresh tokens (7 days) for session management.
- Token rotation on refresh for enhanced security.
- Token blacklisting system to invalidate tokens on logout.
- Automatic token cleanup with MongoDB TTL index.
-
Secure Cookie Management
- HTTP-only cookies for tokens to prevent XSS attacks.
- Secure and SameSite flags for added security.
- Cookie expiration set to token expiry time.
- Cookie clearing on logout for added security.
-
Session Security
- Device limiting (default: 2 devices per user)
- Last used tracking
- Device and IP tracking
- Single device logout
- Force logout from all devices except current
- Individual session termination
-
Password Security
- Passwords are hashed using bcrypt
- Passowrd requirements enforced via express-validator:
- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character
-
Request Protection
- Rate limiting:
- General API: 100 requests per 15 minutes
- Login endpoints: 5 attempts per 15 minutes
- Input validation for all routes
- CORS configuration to prevent cross-origin attacks
- Security headers with Helmet for added protection
- Rate limiting:
-
Environment Security
- Required variable validation at startup
- Default values for optional variables
- Structured configuration object
- Time string parsing for JWT expiry
-
Email Security
- Email verification system with crypto tokens
- Forgot password system with expiring tokens
- Mailtrap for email testing and development
- Email templates for user communication using HTML
The project follows the MVC (Model-View-Controller) pattern:
├── config/
│ └── env.config.js # Centralized configuration
├── controllers/
│ └── user.controller.js # User-related operations
├── middleware/
│ ├── auth.middleware.js # Authentication & authorization
│ ├── rateLimiter.middleware.js # Request rate limiting
│ └── validation.middleware.js # Input validation
├── models/
│ ├── blacklistedTokens.model.js # Revoked tokens
│ ├── refreshToken.model.js # Session management
│ └── user.model.js # User data & authentication
├── routes/
│ └── user.routes.js # API endpoints
├── utils/
│ ├── apiResponse.utils.js # Response formatting
│ ├── auth.utils.js # Authentication helpers
│ ├── cookie.utils.js # Cookie management
│ ├── db.utils.js # Database connection
│ ├── mailer.utils.js # Email functionality
│ ├── session.utils.js # Session management
│ └── token.utils.js # Token generation & handling
├── .env # Environment variables
├── .env.example # Example environment variables
├── .gitignore # Git ignore file
├── index.js # Application entry point
├── package.json # Dependencies and scripts
└── README.md # Project documentation
| Method | Endpoint | Description | Authentication | Rate Limiting |
|---|---|---|---|---|
| GET | /healthcheck |
Check API health status | None | None |
| Method | Endpoint | Description | Authentication | Rate Limiting |
|---|---|---|---|---|
| POST | /api/v1/users/register |
Register a new user | None | General API rate |
| POST | /api/v1/users/login |
Login a user | None | Login rate limit |
| GET | /api/v1/users/verify/:token |
Verify email address | None | None |
| POST | /api/v1/users/forgot-password |
Request password reset email | None | General API rate |
| PUT | /api/v1/users/reset-password/:token |
Reset password with token | None | General API rate |
| POST | /api/v1/users/refresh-token |
Refresh access token | Refresh token | None |
| Method | Endpoint | Description | Authentication | Rate Limiting |
|---|---|---|---|---|
| GET | /api/v1/users/profile |
Get user profile | Access token | General API rate |
| POST | /api/v1/users/logout |
Logout current user | Access token | General API rate |
| Method | Endpoint | Description | Authentication | Rate Limiting |
|---|---|---|---|---|
| GET | /api/v1/users/sessions |
List all active sessions | Access token | General API rate |
| POST | /api/v1/users/logout-all-other-devices |
Logout from all devices except current | Access token | General API rate |
| DELETE | /api/v1/users/sessions/:sessionId |
Terminate specific session | Access token | General API rate |
| Method | Endpoint | Description | Authentication | Rate Limiting |
|---|---|---|---|---|
| GET | /api/v1/users/admin |
Access admin content | Access token + Admin role | General API rate |
- Clone the repository
git clone https://github.com/sagar-1m/01_NodeJS-Authentication-System.git- Navigate to project directory
cd 01_NodeJS-Authentication-System- Install dependencies
npm install- Set up environment variables
cp .env.example .env
# Update the .env file with your own values- Start the server
# Development mode with auto-restart on file changes
npm run dev
# Production mode
npm start- Access the API
# The API base URL: http://localhost:5000
Here are some example requests to get you started with the API using Postman:
Check if the API is up and running:
GET /healthcheckResponse:
{
"status": "Ok",
"message": "Server is running",
"environment": "development",
"uptime": 1234,
"timestamp": "2023-09-15T12:34:56.789Z"
}Register a new user account:
POST /api/v1/users/register
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com",
"password": "Password123!"
}Verify user email with the token sent via email:
GET /api/v1/users/verify/:tokenLogin with verified user credentials:
POST /api/v1/users/login
Content-Type: application/json
{
"email": "john@example.com",
"password": "Password123!"
}Note: The login request will return the access and refresh tokens in the HTTP-only cookies.
Request a password reset email:
POST /api/v1/users/forgot-password
Content-Type: application/json
{
"email": "john@example.com"
}Reset the user password with the token sent via email:
PUT /api/v1/users/reset-password/:token
Content-Type: application/json
{
"password": "NewPassword123!"
}Get a new access token using the refresh token (automatically uses the refresh token cookie):
POST /api/v1/users/refresh-tokenNote: The refresh tokens must be sent in the HTTP-only cookie.
Retrieve the user profile with the access token:
GET /api/v1/users/profile
Cookie: accessToken=<your_access_token>List all active sessions for the user:
GET /api/v1/users/sessions
Cookie: accessToken=<your_access_token>End a specific session by its ID:
DELETE /api/v1/users/sessions/:sessionId
Cookie: accessToken=<your_access_token>Logout from all devices except the current one:
POST /api/v1/users/logout-all-other-devices
Cookie: accessToken=<your_access_token>Access an admin-only route with the access token:
GET /api/v1/users/admin
Cookie: accessToken=<your_access_token>Logout the current user and clear the session:
POST /api/v1/users/logout
Cookie: accessToken=<your_access_token>Note: The logout request will clear the access and refresh tokens from the cookies.
The environment variables are stored in a .env.example file. Create a new file named .env and copy the contents of .env.example into it. Update the values of the environment variables with your own values.
# Server configuration
PORT=5000 # API server port
NODE_ENV=development
FRONTEND_URL=http://localhost:3000 # Frontend URL
BASE_URL=http://localhost:5000 # API base URL
# Database configuration (Option 1: Components)
MONGODB_URI=mongodb+srv://your_username:your_password@your_host/your_database_name
# JWT Configuration
JWT_ACCESS_TOKEN_SECRET=your_very_long_access_token_secret_here
ACCESS_TOKEN_EXPIRESIN=5m
JWT_REFRESH_TOKEN_SECRET=your_very_long_refresh_token_secret_here
REFRESH_TOKEN_EXPIRESIN=2d
# Email Configuration (Mailtrap)
EMAIL_HOST=
EMAIL_PORT=
EMAIL_SECURE=
MAILTRAP_SENDEREMAIL=your_email
SMTP_USER=your_mailtrap_username
SMTP_PASS=your_mailtrap_password
# Security Configuration
MAX_DEVICES_PER_USER=2The application uses three data models: User, BlacklistedToken and RefreshToken. Here's a brief overview of the schema and models:
{
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true,
lowercase: true
},
password: {
type: String,
required: true,
select: false // Hidden from queries
},
role: {
type: String,
enum: ["user", "admin"],
default: "user"
},
isVerified: {
type: Boolean,
default: false
},
// Password reset fields
passwordResetToken: String,
passwordResetTokenTime: Date,
// Email verification fields
verificationToken: String,
verificationTokenTime: Date,
// Timestamps
createdAt: Date,
updatedAt: Date
}{
token: {
type: String,
required: true,
unique: true
},
user: {
type: ObjectId,
ref: "User",
required: true
},
expiresAt: {
type: Date,
required: true,
},
createdAt: Date,
updatedAt: Date
}
blacklistedTokenSchema.index({ expiresAt: 1 }, { expireAfterSeconds: 0 }); // TTL index for auto-cleanup{
token: {
type: String,
required: true,
unique: true
},
user: {
type: ObjectId,
ref: "User",
required: true
},
expiresAt: {
type: Date,
required: true
},
deviceInfo: {
type: String,
required: true
},
ipAddress: String
issuedAt: Date,
lastUsed: Date,
expiresAt: Date,
createdAt: Date,
updatedAt: Date
}- Add social authentication (Google, GitHub, etc.)
- Implement two-factor authentication (2FA)
- Add user profile management endpoints
- Add account lockout after failed login attempts
- Create comprehensive test suite
- Implement geo-location tracking for sessions
- Add suspicious activity detection
Contributions, issues, and feature requests are welcome! 🙌
- Fork the repository
- Create your feature branch: (
git checkout -b feature/amazing-feature) - Commit your changes: (
git commit -am 'Add some amazing feature') - Push to the branch: (
git push origin feature/amazing-feature) - Open a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
- Hitesh Choudhary for their amazing concepts stories
- Piyush Garg for their awesome analogies
- Node.js for the awesome runtime
- Please ⭐️ this repository if this project helped you!