Skip to content
BackendPHP

JWT Authentication Node.js – Secure Login System बनाए 2026

April 20, 2026 18 min read

नमस्ते दोस्तों! 🙏
स्वागत है The Easy Master पर!

क्या तुमने कभी सोचा है – Login system kaise kaam karta hai? Jaise tum Gmail ya Instagram mein login karte ho – password daalte ho – aur access mil jaata hai. Yeh sab authentication ke through hota hai!

JWT authentication Node.js Hindi में समझना बहुत जरूरी है क्योंकि:

  • 99% modern apps JWT use karti hain
  • Stateless authentication – server session store nahi karta
  • Mobile apps, SPAs, microservices – sab JWT use karte hain
  • Interview mein pakka JWT questions puche jayenge

Aaj kya seekhoge?

TopicKya Seekhega?
JWT Kya Hai?JSON Web Token introduction
Authentication vs AuthorizationAntar samjho
JWT StructureHeader, Payload, Signature
JWT Sign & VerifyToken generate aur verify karna
Login SystemComplete API banayenge
Protected RoutesMiddleware se routes secure karna
Refresh TokensToken refresh mechanism
Password Hashingbcrypt se passwords secure

Kya tumhe pata hai?
JWT ka full form JSON Web Token hai – ye stateless hota hai, matlab server ko session store karne ki zaroorat nahi!

तो चलिए शुरू करते हैं – JWT authentication Node.js Hindi सीखने का सफर! 🚀

1. JWT क्या Hai? – Introduction

JWT (JSON Web Token) ek open standard hai (RFC 7519) jo secure data transfer ke liye use hota hai. Authentication mein ye token-based approach provide karta hai.

JWT Flow:

Code
┌─────────────────────────────────────────────────────────────────┐
│                        JWT Authentication Flow                   │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  1. User submits email + password                               │
│           ↓                                                      │
│  2. Server verifies credentials                                  │
│           ↓                                                      │
│  3. Server generates JWT token (signed with secret)             │
│           ↓                                                      │
│  4. Server sends token to client                                 │
│           ↓                                                      │
│  5. Client stores token (localStorage / cookie)                 │
│           ↓                                                      │
│  6. Client sends token in Authorization header                   │
│           ↓                                                      │
│  7. Server verifies token                                        │
│           ↓                                                      │
│  8. Server sends protected data                                  │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Why JWT?

FeatureBenefit
StatelessServer session store nahi karta
ScalableKoi bhi server token verify kar sakta hai
Self-containedUser info token mein hi hoti hai
Cross-platformWeb, mobile, IoT – sab support karte hain

2. Authentication vs Authorization – difference समझो

TermMeaningQuestion
Authentication“Aap kaun ho?”Verify identity (login)
Authorization“Aap kya kar sakte ho?”Check permissions (roles)

Example:

Code
User: Vivek
Password: correct ✅

Authentication PASS → User is verified

Now check authorization:
- Can Vivek VIEW products? ✅ Yes (role: user)
- Can Vivek DELETE products? ❌ No (admin required)

In Code:

Code
// Authentication – check if user is logged in
function authenticate(req, res, next) {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(401).json({ error: 'Unauthorized' });
  
  try {
    const decoded = jwt.verify(token, SECRET);
    req.user = decoded;
    next();
  } catch {
    return res.status(401).json({ error: 'Invalid token' });
  }
}

// Authorization – check if user has permission
function authorize(...roles) {
  return (req, res, next) => {
    if (!roles.includes(req.user.role)) {
      return res.status(403).json({ error: 'Forbidden' });
    }
    next();
  };
}

// Usage
app.get('/api/admin', authenticate, authorize('admin'), (req, res) => {
  res.json({ message: 'Admin access granted' });
});

3. JWT Structure – Header, Payload, Signature

JWT token 3 parts se milkar banta hai, dots (.) se separated:

Code
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwibmFtZSI6IlJhaHVsIiwicm9sZSI6InVzZXIiLCJpYXQiOjE3MTMxNjQ4MDB9.7xHx5xHx5xHx5xHx5xHx5xHx5xHx5xHx5xHx5xHx5xHx5xHx

Part 1: Header (Base64 encoded)

Code
{
  "alg": "HS256",   // Algorithm (HS256, RS256)
  "typ": "JWT"      // Token type
}

Part 2: Payload (Base64 encoded)

Code
{
"id": 1,
"name": "Vivek",
"role": "user",
"iat": 1713164800, // Issued at
"exp": 1713168400, // Expiration (optional)
"aud": "myapp", // Audience
"iss": "myapi" // Issuer
}

Part 3: Signature

Code
signature = HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

JWT Visual:

Code
┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│   Header    │  │  Payload    │  │  Signature  │
├─────────────┤  ├─────────────┤  ├─────────────┤
│ algorithm   │  │ user id     │  │ verify that │
│ token type  │  │ name        │  │ token wasn't│
│             │  │ role        │  │ tampered    │
│             │  │ exp         │  │             │
└─────────────┘  └─────────────┘  └─────────────┘
       │                │                │
       └────────────────┼────────────────┘
                        │
                  Base64 + Secret

4. Project Setup – Dependencies Install

Step 1: Create Project

Code
mkdir jwt-auth-api
cd jwt-auth-api
npm init -y

Step 2: Install Dependencies

Code
# Core dependencies
npm install express jsonwebtoken bcrypt dotenv

# Dev dependencies
npm install -D nodemon

# Optional (validation, cors, helmet)
npm install express-validator cors helmet morgan

Step 3: Basic Server Setup

Code
// server.js
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
const dotenv = require('dotenv');

dotenv.config();

const app = express();
const PORT = process.env.PORT || 3000;

// Middleware
app.use(helmet());
app.use(cors());
app.use(morgan('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Routes
app.use('/api/auth', require('./routes/auth'));
app.use('/api/users', require('./routes/users'));

// Health check
app.get('/health', (req, res) => {
  res.json({ status: 'OK', timestamp: new Date().toISOString() });
});

// 404 handler
app.use('*', (req, res) => {
  res.status(404).json({ error: `Cannot ${req.method} ${req.url}` });
});

// Global error handler
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(err.status || 500).json({
    error: err.message || 'Internal server error'
  });
});

app.listen(PORT, () => {
  console.log(`🚀 Server running on http://localhost:${PORT}`);
});

Step 4: Environment Variables

Code
# .env
PORT=3000
JWT_SECRET=your_super_secret_key_change_this_in_production
JWT_REFRESH_SECRET=your_refresh_secret_key_change_this
JWT_EXPIRES_IN=15m
JWT_REFRESH_EXPIRES_IN=7d
BCRYPT_ROUNDS=10

Step 5: package.json Scripts

Code
{
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js"
  }
}

5. Password Hashing – bcrypt se Secure Karna

bcrypt password hash karne ka library hai – plain text password kabhi store nahi karna chahiye!

Why bcrypt?

  • Salted hashes – same password ka alag hash
  • Adaptive – hash time increase kar sakte ho
  • Slow – brute force attacks mushkil

Hash Password:

Code
// utils/password.js
const bcrypt = require('bcrypt');
const SALT_ROUNDS = parseInt(process.env.BCRYPT_ROUNDS) || 10;

// Hash password
async function hashPassword(plainPassword) {
  const salt = await bcrypt.genSalt(SALT_ROUNDS);
  const hashedPassword = await bcrypt.hash(plainPassword, salt);
  return hashedPassword;
}

// Compare password
async function comparePassword(plainPassword, hashedPassword) {
  return await bcrypt.compare(plainPassword, hashedPassword);
}

module.exports = { hashPassword, comparePassword };

In-Memory Database (for demo):

Code
// db.js (in-memory for learning)
let users = [
  {
    id: 1,
    name: 'Admin User',
    email: 'admin@example.com',
    password: '$2b$10$...', // hashed "admin123"
    role: 'admin',
    createdAt: new Date()
  }
];

let refreshTokens = [];

module.exports = { users, refreshTokens };

6. JWT Sign & Verify – Token Generate Karna

JWT Utils:

Code
// utils/jwt.js
const jwt = require('jsonwebtoken');

const JWT_SECRET = process.env.JWT_SECRET;
const JWT_REFRESH_SECRET = process.env.JWT_REFRESH_SECRET;
const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || '15m';
const JWT_REFRESH_EXPIRES_IN = process.env.JWT_REFRESH_EXPIRES_IN || '7d';

// Generate access token (short lived)
function generateAccessToken(payload) {
  return jwt.sign(payload, JWT_SECRET, { expiresIn: JWT_EXPIRES_IN });
}

// Generate refresh token (long lived)
function generateRefreshToken(payload) {
  return jwt.sign(payload, JWT_REFRESH_SECRET, { expiresIn: JWT_REFRESH_EXPIRES_IN });
}

// Verify access token
function verifyAccessToken(token) {
  try {
    return jwt.verify(token, JWT_SECRET);
  } catch (error) {
    return null;
  }
}

// Verify refresh token
function verifyRefreshToken(token) {
  try {
    return jwt.verify(token, JWT_REFRESH_SECRET);
  } catch (error) {
    return null;
  }
}

// Generate both tokens
function generateTokens(user) {
  const payload = {
    id: user.id,
    email: user.email,
    name: user.name,
    role: user.role
  };
  
  const accessToken = generateAccessToken(payload);
  const refreshToken = generateRefreshToken(payload);
  
  return { accessToken, refreshToken };
}

module.exports = {
  generateAccessToken,
  generateRefreshToken,
  verifyAccessToken,
  verifyRefreshToken,
  generateTokens
};

7. Complete Login/Register API

Auth Routes:

Code
// routes/auth.js
const express = require('express');
const router = express.Router();
const { body, validationResult } = require('express-validator');
const { hashPassword, comparePassword } = require('../utils/password');
const { generateTokens, verifyRefreshToken } = require('../utils/jwt');
const { users, refreshTokens } = require('../db');

let nextId = users.length + 1;

// ============ REGISTER ============
router.post('/register', [
  body('name').notEmpty().withMessage('Name is required').isLength({ min: 2 }),
  body('email').isEmail().withMessage('Valid email is required'),
  body('password').isLength({ min: 6 }).withMessage('Password must be at least 6 characters')
], async (req, res) => {
  // Check validation errors
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ 
      success: false, 
      errors: errors.array() 
    });
  }
  
  const { name, email, password, role = 'user' } = req.body;
  
  // Check if user already exists
  const existingUser = users.find(u => u.email === email);
  if (existingUser) {
    return res.status(409).json({ 
      success: false, 
      error: 'User with this email already exists' 
    });
  }
  
  // Hash password
  const hashedPassword = await hashPassword(password);
  
  // Create new user
  const newUser = {
    id: nextId++,
    name,
    email,
    password: hashedPassword,
    role,
    createdAt: new Date()
  };
  
  users.push(newUser);
  
  // Generate tokens
  const { accessToken, refreshToken } = generateTokens(newUser);
  
  // Store refresh token (in production, use database)
  refreshTokens.push({ token: refreshToken, userId: newUser.id });
  
  // Return user without password
  const { password: _, ...userWithoutPassword } = newUser;
  
  res.status(201).json({
    success: true,
    message: 'User registered successfully',
    data: {
      user: userWithoutPassword,
      accessToken,
      refreshToken
    }
  });
});

// ============ LOGIN ============
router.post('/login', [
  body('email').isEmail().withMessage('Valid email is required'),
  body('password').notEmpty().withMessage('Password is required')
], async (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ 
      success: false, 
      errors: errors.array() 
    });
  }
  
  const { email, password } = req.body;
  
  // Find user
  const user = users.find(u => u.email === email);
  if (!user) {
    return res.status(401).json({ 
      success: false, 
      error: 'Invalid email or password' 
    });
  }
  
  // Check password
  const isPasswordValid = await comparePassword(password, user.password);
  if (!isPasswordValid) {
    return res.status(401).json({ 
      success: false, 
      error: 'Invalid email or password' 
    });
  }
  
  // Generate tokens
  const { accessToken, refreshToken } = generateTokens(user);
  
  // Store refresh token
  refreshTokens.push({ token: refreshToken, userId: user.id });
  
  // Return user without password
  const { password: _, ...userWithoutPassword } = user;
  
  res.json({
    success: true,
    message: 'Login successful',
    data: {
      user: userWithoutPassword,
      accessToken,
      refreshToken
    }
  });
});

// ============ REFRESH TOKEN ============
router.post('/refresh', async (req, res) => {
  const { refreshToken } = req.body;
  
  if (!refreshToken) {
    return res.status(401).json({ 
      success: false, 
      error: 'Refresh token required' 
    });
  }
  
  // Check if refresh token exists in store
  const storedToken = refreshTokens.find(t => t.token === refreshToken);
  if (!storedToken) {
    return res.status(403).json({ 
      success: false, 
      error: 'Invalid refresh token' 
    });
  }
  
  // Verify refresh token
  const decoded = verifyRefreshToken(refreshToken);
  if (!decoded) {
    return res.status(403).json({ 
      success: false, 
      error: 'Invalid or expired refresh token' 
    });
  }
  
  // Find user
  const user = users.find(u => u.id === decoded.id);
  if (!user) {
    return res.status(404).json({ 
      success: false, 
      error: 'User not found' 
    });
  }
  
  // Generate new tokens
  const { accessToken, refreshToken: newRefreshToken } = generateTokens(user);
  
  // Remove old refresh token, add new one
  const index = refreshTokens.findIndex(t => t.token === refreshToken);
  refreshTokens.splice(index, 1);
  refreshTokens.push({ token: newRefreshToken, userId: user.id });
  
  res.json({
    success: true,
    data: {
      accessToken,
      refreshToken: newRefreshToken
    }
  });
});

// ============ LOGOUT ============
router.post('/logout', async (req, res) => {
  const { refreshToken } = req.body;
  
  if (refreshToken) {
    // Remove refresh token from store
    const index = refreshTokens.findIndex(t => t.token === refreshToken);
    if (index !== -1) {
      refreshTokens.splice(index, 1);
    }
  }
  
  res.json({
    success: true,
    message: 'Logged out successfully'
  });
});

// ============ GET CURRENT USER ============
router.get('/me', authenticate, async (req, res) => {
  const user = users.find(u => u.id === req.user.id);
  
  if (!user) {
    return res.status(404).json({ 
      success: false, 
      error: 'User not found' 
    });
  }
  
  const { password, ...userWithoutPassword } = user;
  
  res.json({
    success: true,
    data: userWithoutPassword
  });
});

module.exports = router;

8. Protected Routes – Middleware Banayein

Authentication Middleware:

Code
// middleware/auth.js
const { verifyAccessToken } = require('../utils/jwt');

function authenticate(req, res, next) {
  const authHeader = req.headers.authorization;
  
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return res.status(401).json({ 
      success: false, 
      error: 'Access token required' 
    });
  }
  
  const token = authHeader.split(' ')[1];
  const decoded = verifyAccessToken(token);
  
  if (!decoded) {
    return res.status(401).json({ 
      success: false, 
      error: 'Invalid or expired access token' 
    });
  }
  
  req.user = decoded;
  next();
}

// Authorization middleware
function authorize(...roles) {
  return (req, res, next) => {
    if (!roles.includes(req.user.role)) {
      return res.status(403).json({ 
        success: false, 
        error: 'Forbidden: Insufficient permissions' 
      });
    }
    next();
  };
}

// Optional: Check if user owns resource
function isOwnerOrAdmin(getResourceUserId) {
  return async (req, res, next) => {
    const resourceUserId = await getResourceUserId(req);
    
    if (req.user.role === 'admin' || req.user.id === resourceUserId) {
      return next();
    }
    
    return res.status(403).json({ 
      success: false, 
      error: 'Forbidden: You can only access your own resources' 
    });
  };
}

module.exports = { authenticate, authorize, isOwnerOrAdmin };

Protected User Routes:

Code
// routes/users.js
const express = require('express');
const router = express.Router();
const { authenticate, authorize } = require('../middleware/auth');
const { users } = require('../db');

// All routes below require authentication
router.use(authenticate);

// Get all users (admin only)
router.get('/', authorize('admin'), (req, res) => {
  const safeUsers = users.map(({ password, ...user }) => user);
  res.json({
    success: true,
    count: safeUsers.length,
    data: safeUsers
  });
});

// Get current user profile
router.get('/profile', (req, res) => {
  const user = users.find(u => u.id === req.user.id);
  
  if (!user) {
    return res.status(404).json({ 
      success: false, 
      error: 'User not found' 
    });
  }
  
  const { password, ...userWithoutPassword } = user;
  res.json({ success: true, data: userWithoutPassword });
});

// Get user by ID (admin only)
router.get('/:id', authorize('admin'), (req, res) => {
  const id = parseInt(req.params.id);
  const user = users.find(u => u.id === id);
  
  if (!user) {
    return res.status(404).json({ 
      success: false, 
      error: 'User not found' 
    });
  }
  
  const { password, ...userWithoutPassword } = user;
  res.json({ success: true, data: userWithoutPassword });
});

// Update user profile
router.put('/profile', (req, res) => {
  const { name, email } = req.body;
  const userIndex = users.findIndex(u => u.id === req.user.id);
  
  if (userIndex === -1) {
    return res.status(404).json({ 
      success: false, 
      error: 'User not found' 
    });
  }
  
  users[userIndex] = {
    ...users[userIndex],
    name: name || users[userIndex].name,
    email: email || users[userIndex].email,
    updatedAt: new Date()
  };
  
  const { password, ...userWithoutPassword } = users[userIndex];
  res.json({ success: true, data: userWithoutPassword });
});

// Delete user (admin only)
router.delete('/:id', authorize('admin'), (req, res) => {
  const id = parseInt(req.params.id);
  const userIndex = users.findIndex(u => u.id === id);
  
  if (userIndex === -1) {
    return res.status(404).json({ 
      success: false, 
      error: 'User not found' 
    });
  }
  
  users.splice(userIndex, 1);
  res.json({ success: true, message: 'User deleted successfully' });
});

module.exports = router;

9. Refresh Token – Token Refresh Mechanism

Why Refresh Tokens?

Access TokenRefresh Token
Short lived (15 min)Long lived (7 days)
Used for API accessUsed to get new access token
Stored in memoryStored in httpOnly cookie or secure storage
If stolen, limited damageCan be revoked

Refresh Token Flow:

Code
┌─────────────────────────────────────────────────────────────────┐
│                    Refresh Token Flow                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  1. User logs in → gets access_token + refresh_token            │
│                         ↓                                        │
│  2. User uses access_token for API calls                        │
│                         ↓                                        │
│  3. Access token expires (401 Unauthorized)                     │
│                         ↓                                        │
│  4. Client calls /auth/refresh with refresh_token               │
│                         ↓                                        │
│  5. Server verifies refresh_token → issues new tokens           │
│                         ↓                                        │
│  6. Client retries original request with new access_token       │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Client Side Implementation (Frontend):

Code
// api.js (frontend example)
let accessToken = localStorage.getItem('accessToken');
let refreshToken = localStorage.getItem('refreshToken');

async function apiCall(url, options = {}) {
  try {
    const response = await fetch(url, {
      ...options,
      headers: {
        ...options.headers,
        'Authorization': `Bearer ${accessToken}`
      }
    });
    
    if (response.status === 401) {
      // Token expired, try to refresh
      const newTokens = await refreshAccessToken();
      if (newTokens) {
        // Retry with new token
        options.headers = {
          ...options.headers,
          'Authorization': `Bearer ${newTokens.accessToken}`
        };
        return fetch(url, options);
      }
    }
    
    return response;
  } catch (error) {
    throw error;
  }
}

async function refreshAccessToken() {
  const response = await fetch('/api/auth/refresh', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ refreshToken })
  });
  
  if (response.ok) {
    const { data } = await response.json();
    accessToken = data.accessToken;
    refreshToken = data.refreshToken;
    localStorage.setItem('accessToken', accessToken);
    localStorage.setItem('refreshToken', refreshToken);
    return data;
  }
  
  // Refresh failed, redirect to login
  window.location.href = '/login';
  return null;
}

10. Logout System – Token Blacklist

In-Memory Blacklist (for demo):

Code
// db.js (updated)
let users = [];
let refreshTokens = [];
let blacklistedTokens = []; // Track invalidated tokens

module.exports = { users, refreshTokens, blacklistedTokens };

Logout with Blacklist:

Code
// routes/auth.js (updated logout)
const { users, refreshTokens, blacklistedTokens } = require('../db');

// Logout
router.post('/logout', async (req, res) => {
  const authHeader = req.headers.authorization;
  const { refreshToken } = req.body;
  
  // Blacklist access token
  if (authHeader && authHeader.startsWith('Bearer ')) {
    const accessToken = authHeader.split(' ')[1];
    const decoded = verifyAccessToken(accessToken);
    if (decoded) {
      blacklistedTokens.push({
        token: accessToken,
        expiresAt: decoded.exp
      });
    }
  }
  
  // Remove refresh token
  if (refreshToken) {
    const index = refreshTokens.findIndex(t => t.token === refreshToken);
    if (index !== -1) {
      refreshTokens.splice(index, 1);
    }
  }
  
  res.json({
    success: true,
    message: 'Logged out successfully'
  });
});

// Updated authenticate middleware with blacklist check
function authenticate(req, res, next) {
  const authHeader = req.headers.authorization;
  
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return res.status(401).json({ error: 'Access token required' });
  }
  
  const token = authHeader.split(' ')[1];
  
  // Check if token is blacklisted
  const isBlacklisted = blacklistedTokens.some(t => t.token === token);
  if (isBlacklisted) {
    return res.status(401).json({ error: 'Token has been invalidated' });
  }
  
  const decoded = verifyAccessToken(token);
  if (!decoded) {
    return res.status(401).json({ error: 'Invalid or expired token' });
  }
  
  req.user = decoded;
  next();
}

11. Real-world Project – Complete Auth API

Project Structure:

Code
jwt-auth-api/
├── server.js
├── .env
├── package.json
├── db.js                      # In-memory database
├── utils/
│   ├── jwt.js                 # JWT utilities
│   └── password.js            # bcrypt utilities
├── middleware/
│   └── auth.js                # Auth middleware
├── routes/
│   ├── auth.js                # Auth routes
│   └── users.js               # User routes
└── validators/
    └── authValidator.js       # Input validation

Testing the API:

Code
# 1. Register
curl -X POST http://localhost:3000/api/auth/register \
-H "Content-Type: application/json" \
-d '{"name":"Vivek","email":"vivek@example.com","password":"123456"}'

# 2. Login
curl -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"vivek@example.com","password":"123456"}'

# 3. Get Profile (with token)
curl -X GET http://localhost:3000/api/users/profile \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# 4. Refresh Token
curl -X POST http://localhost:3000/api/auth/refresh \
-H "Content-Type: application/json" \
-d '{"refreshToken":"YOUR_REFRESH_TOKEN"}'

# 5. Logout
curl -X POST http://localhost:3000/api/auth/logout \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"refreshToken":"YOUR_REFRESH_TOKEN"}'

12. Common Mistakes + Solutions

Mistake 1: Storing JWT in localStorage (XSS risk)

Code
// ❌ Security risk – XSS attacks
localStorage.setItem('token', token);

// ✅ Better – httpOnly cookie
res.cookie('token', token, {
  httpOnly: true,
  secure: process.env.NODE_ENV === 'production',
  sameSite: 'strict',
  maxAge: 15 * 60 * 1000
});

Mistake 2: Not validating email/password

Code
// ❌ No validation
app.post('/login', (req, res) => {
  const user = users.find(u => u.email === req.body.email);
  // ...
});

// ✅ Validate input
app.post('/login', [
  body('email').isEmail(),
  body('password').notEmpty()
], handler);

Mistake 3: Hardcoding JWT secret

Code
// ❌ Never hardcode
const JWT_SECRET = 'mysecret';

// ✅ Use environment variable
const JWT_SECRET = process.env.JWT_SECRET;

Mistake 4: Not expiring tokens

Code
// ❌ Token never expires
jwt.sign(payload, secret);

// ✅ Set expiration
jwt.sign(payload, secret, { expiresIn: '15m' });

Mistake 5: Storing sensitive data in JWT

Code
// ❌ Don't store password in token
jwt.sign({ id, email, password }, secret);

// ✅ Store only necessary data
jwt.sign({ id, email, role }, secret);

13. Quick Cheat Sheet

JWT Commands:

Code
# Generate secret
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

# Install dependencies
npm install jsonwebtoken bcrypt dotenv

Code Snippets:

Code
// Generate token
const token = jwt.sign({ id: user.id }, SECRET, { expiresIn: '15m' });

// Verify token
const decoded = jwt.verify(token, SECRET);

// Hash password
const hash = await bcrypt.hash(password, 10);

// Compare password
const isValid = await bcrypt.compare(password, hash);

Token Expiration Values:

ValueMeaning
15m15 minutes
1h1 hour
1d1 day
7d7 days
30d30 days

14. FAQ

Q1: JWT authentication Node.js Hindi में सबसे important concept kya hai?
Token verification middleware – ye har protected route mein token check karta hai aur user ko request object mein attach karta hai।

Q2: JWT vs Session – kya use karein?
JWT – stateless, scalable, microservices के लिए। Session – stateful, easy to revoke, traditional monolith के लिए।

Q3: Refresh token kyun chahiye?
Access token short lived hota hai (security). Refresh token se naya access token milta hai bina login kare।

Q4: JWT secret kaise generate karein?
crypto.randomBytes(32).toString('hex') – 64 character long random string।

Q5: bcrypt ke genSalt aur hash mein kya antar hai?
genSalt salt generate karta hai, hash salt + password se hash banata hai। hash function internally salt bhi generate kar sakta hai।

Q6: Token store kahan karein?
Mobile apps – secure storage। Web – httpOnly cookie (best) ya memory (OK)।

Q7: Token revoke kaise karein?
Blacklist maintain karo या database mein token version store karo।

Q8: JWT mein कितना data store kar sakte hain?
Limited – JWT size small hona chahiye (1KB से कम)। Zyada data database mein store karo।

Q9: 401 vs 403 – kab kya return karein?
401 – Unauthorized (token missing/invalid)। 403 – Forbidden (token valid but insufficient permissions)।

Q10: Production mein JWT ke saath aur kya use karein?
Rate limiting, CORS, helmet, express-validator, HTTPS, environment variables।

15. Conclusion

बहुत बढ़िया दोस्तों! आज हमने JWT authentication Node.js Hindi को पूरी detail में समझा।

Quick Recap:

ConceptKey Takeaway
JWTJSON Web Token – stateless authentication
Authentication vs AuthorizationAuth =你是谁, Authz = क्या कर सकते हो
bcryptPassword hashing – plain text kabhi store mat karo
Access TokenShort lived (15 min) – API access के लिए
Refresh TokenLong lived (7 days) – नया access token लाने के लिए
MiddlewareProtected routes के लिए

Mera personal experience:

JWT authentication seekhne ke baad maine apni sari APIs secure karni shuru kar di। Pehle sessions use karta tha, lekin microservices mein JWT bohot better raha। Bas yaad rakho – JWT secret ko environment variable mein rakho aur kabhi hardcode mat karo!

Tum bhi ye steps follow karo:

  1. ✅ JWT concept samjho
  2. ✅ bcrypt se password hash karo
  3. ✅ Login/Register API banao
  4. ✅ Protected routes middleware implement karo
  5. ✅ Refresh token mechanism add karo

अब तुम्हारी बारी है!

नीचे comment में बताओ:

  1. तुम session use karoge ya JWT? क्यों?
  2. तुमने कभी token refresh implement kiya hai?
  3. अगला topic क्या चाहिए? (Docker with Node.js? GraphQL? WebSockets?)

The Easy Master पर बने रहो। Happy Secure Coding! 🔐🚀

Resources

Additional Resources

TheEasyMaster

Author at The Easy Master.

Previous
Prisma ORM MongoDB से Database Connect कैसे करें – Easy Tutorial Hindi
Next
WebSockets Node.js – Live Chat App कैसे बनाएं (Socket.io)

Related posts

Leave a Reply

Your email address will not be published. Required fields are marked *