A comprehensive Node.js API template with professional OAuth authentication implementation using Passport.js, supporting Google and Facebook login.
- OAuth Authentication: Google and Facebook login integration
- JWT Token Management: Secure token-based authentication
- User Management: Complete user CRUD operations
- Email Verification: OTP-based email verification
- Password Reset: Secure password reset functionality
- File Upload: Multer-based file upload system
- Error Handling: Comprehensive error handling and logging
- Validation: Zod schema validation
- Database: MongoDB with Mongoose ODM
- Logging: Winston-based logging system
- Security: Helmet, CORS, rate limiting
- Google OAuth 2.0: Full Google login integration
- Facebook OAuth: Facebook login integration
- User clicks OAuth login button
- Redirected to provider (Google/Facebook)
- User authenticates with provider
- Provider redirects back to callback URL
- User data is processed and JWT tokens are generated
- User is redirected to frontend with tokens
GET /api/v1/auth/google - Initiate Google OAuth
GET /api/v1/auth/google/callback - Google OAuth callback
GET /api/v1/auth/facebook - Initiate Facebook OAuth
GET /api/v1/auth/facebook/callback - Facebook OAuth callback
Create a .env file in the root directory:
# Server Configuration
NODE_ENV=development
PORT=8002
IP_ADDRESS=localhost
FRONTEND_URL=http://localhost:3000
BACKEND_URL=http://localhost:8002
# Database
DATABASE_URL=mongodb://localhost:27017/your_database
# JWT Configuration
JWT_SECRET=your_jwt_secret_key
JWT_EXPIRE_IN=1d
JWT_REFRESH_SECRET=your_jwt_refresh_secret
JWT_REFRESH_EXPIRE_IN=7d
# OAuth Configuration
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
GOOGLE_CALLBACK_URL=http://localhost:8002/api/v1/auth/google/callback
FACEBOOK_CLIENT_ID=your_facebook_client_id
FACEBOOK_CLIENT_SECRET=your_facebook_client_secret
# Email Configuration
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USER=[email protected]
EMAIL_PASS=your_email_password
EMAIL_FROM=[email protected]
EMAIL_HEADER_NAME=Your App Name
# Session
EXPRESS_SESSION_SECRET_KEY=your_session_secret
# Other Configuration
BCRYPT_SALT_ROUNDS=12
ALLOWED_ORIGINS=http://localhost:3000
RESET_TOKEN_EXPIRE_TIME=10m- Go to Google Cloud Console
- Create a new project or select existing one
- Enable Google+ API
- Go to Credentials β Create Credentials β OAuth 2.0 Client ID
- Set Application Type to "Web application"
- Add authorized redirect URIs:
http://localhost:8002/api/v1/auth/google/callback(development)https://yourdomain.com/api/v1/auth/google/callback(production)
- Copy Client ID and Client Secret to your
.envfile
- Go to Facebook Developers
- Create a new app
- Add Facebook Login product
- Configure OAuth settings:
- Valid OAuth Redirect URIs:
http://localhost:8002/api/v1/auth/facebook/callback
- Valid OAuth Redirect URIs:
- Copy App ID and App Secret to your
.envfile
# Install dependencies
npm install
# Run in development mode
npm run dev
# Build for production
npm run build
# Start production server
npm startPOST /api/v1/auth/login - User login
POST /api/v1/auth/verify-email - Verify email with OTP
POST /api/v1/auth/forget-password - Request password reset
POST /api/v1/auth/reset-password - Reset password
POST /api/v1/auth/change-password - Change password
POST /api/v1/auth/refresh-token - Refresh JWT token
POST /api/v1/auth/resend-otp - Resend OTP
GET /api/v1/auth/google - Google OAuth login
GET /api/v1/auth/google/callback - Google OAuth callback
GET /api/v1/auth/facebook - Facebook OAuth login
GET /api/v1/auth/facebook/callback - Facebook OAuth callback
GET /api/v1/users/profile - Get user profile
PATCH /api/v1/users/profile - Update user profile
POST /api/v1/users - Create new user
interface IUser {
name: string;
role: USER_ROLES;
email: string;
password?: string; // Optional for OAuth users
image?: string;
status: 'active' | 'blocked';
verified: boolean;
isDeleted: boolean;
stripeCustomerId: string;
// OAuth fields
googleId?: string;
facebookId?: string;
oauthProvider?: 'google' | 'facebook';
authentication?: {
isResetPassword: boolean;
oneTimeCode: number;
expireAt: Date;
};
}- User clicks "Login with Google/Facebook"
- OAuth provider authenticates user
- System checks if user exists by OAuth ID
- If not found, checks by email
- If email exists, links OAuth account to existing user
- If no user found, creates new user with OAuth data
- User is auto-verified and logged in
- JWT tokens are generated and returned
- User clicks "Login with Google/Facebook"
- OAuth provider authenticates user
- System finds user by OAuth ID
- User is logged in with JWT tokens
- Users can link multiple OAuth providers to same email
- System prevents duplicate accounts
- OAuth users are auto-verified
- OAuth users cannot use password login
- Password Hashing: bcrypt with configurable salt rounds
- JWT Tokens: Secure token-based authentication
- Session Management: Express-session for OAuth flows
- CORS: Configurable CORS settings
- Rate Limiting: Built-in rate limiting
- Input Validation: Zod schema validation
- Error Handling: Comprehensive error handling
- Logging: Winston-based logging system
The API includes comprehensive error handling:
- Validation Errors: Zod schema validation errors
- Authentication Errors: JWT and OAuth errors
- Database Errors: MongoDB connection and query errors
- Business Logic Errors: Custom application errors
- Global Error Handler: Centralized error processing
The application uses Winston for logging:
- Success Logs: API requests and responses
- Error Logs: Application errors and exceptions
- Daily Rotation: Log files rotate daily
- Multiple Levels: Different log levels for different purposes
# Run with hot reload
npm run dev
# Lint code
npm run lint
# Fix linting issues
npm run lint:fix
# Format code
npm run format
# Seed admin user
npm run seed- Set
NODE_ENV=production - Configure production database
- Set secure JWT secrets
- Configure OAuth callback URLs
- Set up proper CORS origins
- Configure email settings
- Set up logging and monitoring
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
This project is licensed under the ISC License.
Happy Coding! π Thank you for using the Backend Template! π΄ββοΈ
Here's how you can set up your Node.js project with the required dependencies:
1. Initialize the Project:
Create a package.json file for managing your project dependencies.
npm init -y2. Install Required Packages:
Add essential libraries and tools for your application:
npm install express # Web framework for building APIs
npm install cors # Enables Cross-Origin Resource Sharing
npm install dotenv # Manages environment variables
npm install mongoose # MongoDB object modeling tool3. Add TypeScript Support:
Install TypeScript type definitions for the above libraries:
npm install @types/express @types/node @types/cors --save-dev4. Install Development Tools:
Add nodemon for automatic server restarts during development:
npm install -D nodemonWe need to add a typescript package in our project, so that we can use the TypeScript compiler and other related tools.
npm i -D typescriptThis command will add typescript package as a dev-dependency in our project.
Now, we need to add typescript config file, for that we will use the below given command.
tsc --initThis will create a tsconfig.json file, with the default compiler configurations shown in the image below.
In the tsconfig.json file, remove the comments on the rootDir option and modify it, to set src as root directory for typescript.
"rootDir": "./src",
Similarly, do this for outDir option as well
"outDir": "./dist",
All .js files will be created in this build folder after compiling the .ts files which are inside the src folder.
For adding eslint, we will install the required packages given below.
npm i -D [email protected] @eslint/js @types/eslint__js typescript typescript-eslintNow make a eslint.config.mjs file in the root of the project director.
npx eslint --initAt this point you may see that your version of eslint: "^9.14.0" has been changed to eslint: "^9.15.0"
if that happens remove the eslint : npm remove eslint Then re-install: npm i -D [email protected]
Now add the following code inside it.
{
ignores: ["node_modules", "dist"],
rules: {
"no-unused-vars": "error",
},
},import globals from 'globals';
import pluginJs from '@eslint/js';
import tseslint from 'typescript-eslint';
/** @type {import('eslint').Linter.Config[]} */
export default [
{ files: ['**/*.{js,mjs,cjs,ts}'] },
{ languageOptions: { globals: globals.node } },
pluginJs.configs.recommended,
...tseslint.configs.recommended,
{
ignores: ['node_modules', 'dist'],
rules: {
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': 'error',
'no-unused-expressions': 'error',
'prefer-const': 'error',
'no-undef': 'error',
'no-console': 'warn',
},
},
];Now in the terminal, you can run npm eslint . You can see that eslint is working.
We can also add scripts for eslint in the package.json file.
"scripts": {
"lint": "eslint src/**/*.ts",
"lint:fix": "eslint src/**/*.ts --fix"
},Add the prettier package in your project.
npm i -D --exact prettierNow create .prettierrc and .prettierignore file in the root of your project.
Include basic configurations for prettier in the .prettierrc file.
{
"semi": true,
"singleQuote": true
}Also, we need to tell prettier which files to not format So inside .prettierignore include the following.
dist;Finally we can add scripts for prettier as well in the package.json file.
"format": "prettier . --write"
ts-node-dev Installation and Usage
Why install and use ts-node-dev?
Installation:
ts-node-devis a development dependency for TypeScript projects.
Install it using:
npm i ts-node-dev --save-devUsage:
-
It runs TypeScript files directly, so you don't need to manually compile them using tsc.
-
It automatically restarts the server when file changes are detected, making development faster.
-
Command to start your server:
npx ts-node-dev --transpile-only src/server.ts"scripts": {
"build": "tsc", # Compiles TypeScript files to JavaScript
"start:dev": "npx ts-node-dev --transpile-only src/server.ts", # Runs the server in development mode with hot-reloading
"start:prod": "node ./dist/server.js", # Starts the server in production mode
"start": "nodemon ./dist/server.js", # Runs the production build with automatic restarts
"lint": "eslint src/**/*.ts", # Checks code style and errors using ESLint
"lint:fix": "eslint src/**/*.ts --fix", # Fixes code style issues automatically
"format": "prettier . --write" # Formats code consistently with Prettier
}