npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

jwt-middleware-auth

v2.1.5

Published

A comprehensive middleware library for JWT authentication and role-based authorization in Express.js

Downloads

620

Readme

JWT Middleware Auth

A comprehensive middleware library for JWT authentication and role-based authorization in Express.js applications.

Installation

npm install jwt-middleware-auth

Dependencies

This package requires jsonwebtoken:

npm install jsonwebtoken@^9.0.3

Usage

Basic Setup

const express = require('express');
const { verifyToken, authorizeRoles } = require('jwt-middleware-auth');

const app = express();
const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key';

// Public route
app.get('/api/public', (req, res) => {
  res.json({ message: 'Public data' });
});

// Protected route - requires authentication
app.get('/api/profile', verifyToken(JWT_SECRET), (req, res) => {
  res.json({ user: req.user });
});

// Role-based route - requires specific role
app.get('/api/admin', verifyToken(JWT_SECRET), authorizeRoles('admin'), (req, res) => {
  res.json({ message: 'Admin data' });
});

Token Format

Tokens should be sent in the request header:

token: Bearer <your-jwt-token>

Example:

token: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Available Middlewares

Authentication Middlewares

verifyToken(secret)

Verifies JWT token and populates req.user with decoded payload.

app.get('/api/protected', verifyToken(JWT_SECRET), (req, res) => {
  // req.user contains: { id, role, email, ... }
  res.json({ userId: req.user.id });
});

Response on failure:

  • 401 - Token not provided or invalid token

Authorization Middlewares

authorizeRoles(...allowedRoles)

Checks if authenticated user has one of the allowed roles. Must be used after verifyToken.

// Single role
app.get('/api/admin-only', 
  verifyToken(JWT_SECRET), 
  authorizeRoles('admin'), 
  controller
);

// Multiple roles
app.get('/api/management', 
  verifyToken(JWT_SECRET), 

### Request Validation Middlewares

#### `validateDashboardLogin`

Validates the dashboard login request body.

**Rules:**
- `role` must NOT be provided
- `email` is required
- `password` is required unless `google` is truthy

```javascript
const express = require('express');
const { validateDashboardLogin } = require('jwt-middleware-auth');

const router = express.Router();

router.post('/dashboard/login', validateDashboardLogin, loginController);

Failure behavior:

  • Returns 400 with a JSON { message } describing the validation error.

    authorizeRoles('admin', 'manager', 'SuperManager'), controller );


**Response on failure:**
- `401` - User not authenticated
- `403` - User doesn't have required role

**Supported roles:**
- `user` - Regular user
- `admin` - Administrator
- `seller` - Store seller/vendor
- `paymentManager` - Payment processing manager
- `manager` - General manager
- `SuperManager` - Super administrator

---

#### `verifyTokenAndAuthorization(secret)`

Allows access if user is updating their own account OR is an admin.

```javascript
// User can update their own profile, or admin can update any profile
app.put('/api/users/:id', 
  verifyTokenAndAuthorization(JWT_SECRET), 
  updateUserController
);

Access granted when:

  • req.user.id === req.params.id (own account)
  • req.user.role === 'admin' (admin override)

verifyAdmin(secret)

Verifies user has admin privileges.

app.delete('/api/users/:id', 
  verifyAdmin(JWT_SECRET), 
  deleteUserController
);

Access granted when:

  • req.user.isAdmin === true

verifyManager(secret)

Allows access if user is a manager or accessing their own resource.

app.get('/api/reports/:id', 
  verifyManager(JWT_SECRET), 
  getReportController
);

Access granted when:

  • req.user.id == req.params.id (own resource)
  • req.user.role == 'manager' (manager access)

verifySeller(secret)

Allows access if user is a seller, payment manager, or accessing their own resource.

app.get('/api/stores/:id', 
  verifySeller(JWT_SECRET), 
  getStoreController
);

Access granted when:

  • req.user.id == req.params.id (own resource)
  • req.user.role == 'seller' (seller access)
  • req.user.role == 'paymentManager' (payment manager access)

verifySellerRole(secret)

Focused role validation for sellers - ideal for resource creation.

app.post('/api/offers', 
  verifySellerRole(JWT_SECRET), 
  createOfferController
);

Access granted when:

  • req.user.role === 'seller'
  • req.user.role === 'paymentManager'

verifySellerOrAdmin(secret)

Allows access for sellers, managers, admins, or super managers.

app.get('/api/store/:id/orders', 
  verifySellerOrAdmin(JWT_SECRET), 
  getOrdersController
);

Access granted when:

  • req.user.role is one of: admin, seller, manager, SuperManager

Advanced Middlewares

verifyTokenAndOwnership(secret, getResourceOwnerId)

Higher-order middleware that verifies token and checks resource ownership.

const { verifyTokenAndOwnership } = require('jwt-middleware-auth');
const Offer = require('./models/Offer');

// Define ownership check function
const checkOfferOwnership = async (req) => {
  const offer = await Offer.findById(req.params.id);
  if (!offer) {
    throw new Error('Offer not found');
  }
  return offer.sellerId; // Return the owner ID
};

// Apply to route
app.put('/api/offers/:id', 
  verifyTokenAndOwnership(JWT_SECRET, checkOfferOwnership), 
  updateOfferController
);

Parameters:

  • secret - JWT secret key
  • getResourceOwnerId - Async function that returns the resource owner's ID

Access granted when:

  • ownerId === req.user.id (user owns the resource)

Responses:

  • 404 - Resource not found
  • 403 - User doesn't own the resource
  • 500 - Error during ownership verification

Complete Examples

User Management API

const express = require('express');
const { 
  verifyToken, 
  verifyTokenAndAuthorization,
  verifyAdmin 
} = require('jwt-middleware-auth');

const app = express();
const JWT_SECRET = process.env.JWT_SECRET;

// Get own profile or any profile (admin)
app.get('/api/users/:id', 
  verifyTokenAndAuthorization(JWT_SECRET), 
  (req, res) => {
    // Fetch and return user
  }
);

// Update own profile or any profile (admin)
app.put('/api/users/:id', 
  verifyTokenAndAuthorization(JWT_SECRET), 
  (req, res) => {
    // Update user
  }
);

// Delete user (admin only)
app.delete('/api/users/:id', 
  verifyAdmin(JWT_SECRET), 
  (req, res) => {
    // Delete user
  }
);

// List all users (admin only)
app.get('/api/users', 
  verifyAdmin(JWT_SECRET), 
  (req, res) => {
    // Return all users
  }
);

E-commerce Store API

const { 
  verifyToken, 
  authorizeRoles,
  verifySellerRole,
  verifyTokenAndOwnership 
} = require('jwt-middleware-auth');

const Store = require('./models/Store');

// Get store ownership
const checkStoreOwnership = async (req) => {
  const store = await Store.findById(req.params.id);
  if (!store) throw new Error('Store not found');
  return store.ownerId;
};

// Create store (seller only)
app.post('/api/stores', 
  verifySellerRole(JWT_SECRET), 
  createStoreController
);

// Update own store
app.put('/api/stores/:id', 
  verifyTokenAndOwnership(JWT_SECRET, checkStoreOwnership), 
  updateStoreController
);

// View store analytics (seller, manager, admin)
app.get('/api/stores/:id/analytics', 
  verifyToken(JWT_SECRET),
  authorizeRoles('seller', 'manager', 'admin'), 
  getAnalyticsController
);

// Approve store (admin only)
app.post('/api/stores/:id/approve', 
  verifyToken(JWT_SECRET),
  authorizeRoles('admin'), 
  approveStoreController
);

Multi-Role Management System

const { verifyToken, authorizeRoles } = require('jwt-middleware-auth');

// Dashboard access - multiple roles
app.get('/api/dashboard', 
  verifyToken(JWT_SECRET),
  authorizeRoles('admin', 'manager', 'SuperManager'),
  (req, res) => {
    res.json({ dashboard: 'data' });
  }
);

// Financial reports - restricted roles
app.get('/api/reports/financial', 
  verifyToken(JWT_SECRET),
  authorizeRoles('admin', 'paymentManager', 'SuperManager'),
  (req, res) => {
    res.json({ reports: 'financial data' });
  }
);

// System settings - super admin only
app.put('/api/settings', 
  verifyToken(JWT_SECRET),
  authorizeRoles('SuperManager'),
  (req, res) => {
    res.json({ message: 'Settings updated' });
  }
);

Error Responses

All middlewares return consistent error responses:

401 Unauthorized

{
  "message": "Token is not provided"
}
{
  "message": "Invalid Token"
}
{
  "message": "Authentication required"
}

403 Forbidden

{
  "message": "You are not authorized"
}
{
  "message": "Access denied. Insufficient permissions."
}
{
  "message": "Seller role required"
}
{
  "message": "You are not authorized to access this resource"
}

404 Not Found

{
  "message": "Resource not found"
}

500 Internal Server Error

{
  "message": "Error verifying resource ownership"
}

JWT Payload Structure

Your JWT tokens should include:

{
  id: 'user-id',           // Required for ownership checks
  role: 'user',            // Required for role-based access
  isAdmin: false,          // Optional for admin checks
  email: '[email protected]', // Optional
  // ... other claims
}

Best Practices

  1. Use environment variables for secrets - Never hardcode JWT secrets
  2. Chain middlewares properly - Always use verifyToken before authorization middlewares
  3. Choose appropriate middleware - Use specific middlewares (e.g., authorizeRoles) over general ones
  4. Handle errors gracefully - Use error middleware to catch and format authentication errors
  5. Implement token refresh - Consider implementing refresh token mechanism for better security
  6. Short-lived tokens - Use short expiration times for access tokens
  7. Validate token payload - Ensure JWT payload contains required fields (id, role)

Security Considerations

  • Store JWT secrets securely (environment variables, secret managers)
  • Use HTTPS in production to prevent token interception
  • Implement token expiration and refresh mechanisms
  • Consider token revocation strategy for logout
  • Validate and sanitize all user inputs
  • Use strong, random secret keys (minimum 32 characters)
  • Implement rate limiting on authentication endpoints
  • Log authentication failures for security monitoring

Middleware Comparison

| Middleware | Authentication | Authorization | Use Case | |------------|----------------|---------------|----------| | verifyToken | ✅ | ❌ | Basic authentication | | authorizeRoles | ❌* | ✅ | Role-based access | | verifyTokenAndAuthorization | ✅ | ✅ | Self or admin access | | verifyAdmin | ✅ | ✅ | Admin-only access | | verifyManager | ✅ | ✅ | Manager or self access | | verifySeller | ✅ | ✅ | Seller/payment manager or self | | verifySellerRole | ✅ | ✅ | Seller role validation | | verifySellerOrAdmin | ✅ | ✅ | Elevated privileges | | verifyTokenAndOwnership | ✅ | ✅ | Resource ownership |

*Requires verifyToken to be called first

License

MIT