Elysia Tools

在一个清晰的工作台里浏览工具、案例、可视化和主题指南。

热门分类

专题

语言
ZHESPTRUFRDEEN

Elysia Tools

导航

安全

JWT 示例

从基础令牌结构到高级安全实现的全面JWT示例

案例

这个案例集合中的条目

文本简单

JWT令牌

理解JWT令牌

难度

1/10

预计时间

1 min

plaintext
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRfaWQiOiJZekV6TUdkb01ISm5PSEJpT0cxaWJEaHlOVEE9IiwicmVzcG9uc2VfdHlwZSI6ImNvZGUiLCJzY29wZSI6ImludHJvc2NwZWN0X3Rva2VucywgcmV2b2tlX3Rva2VucyIsImlzcyI6ImJqaElSak0xY1hwYWEyMXpkV3RJU25wNmVqbE1iazQ0YlRsTlpqazNkWEU9Iiwic3ViIjoiWXpFek1HZG9NSEpuT0hCaU9HMWliRGh5TlRBPSIsImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0Ojg0NDMve3RpZH0ve2FpZH0vb2F1dGgyL2F1dGhvcml6ZSIsImp0aSI6IjE1MTYyMzkwMjIiLCJleHAiOiIyMDIxLTA1LTE3VDA3OjA5OjQ4LjAwMCswNTQ1In0.IxvaN4ER-PlPgLYzfRhk_JiY4VAow3GNjaK5rYCINFsEPa7VaYnRsaCmQVq8CTgddihEPPXet2laH8_c3WqxY4AeZO5eljwSCobCHzxYdOoFKbpNXIm7dqHg_5xpQz-YBJMiDM1ILOEsER8ADyF4NC2sN0K_0t6xZLSAQIRrHvpGOrtYr5E-SllTWHWPmqCkX2BUZxoYNK2FWgQZpuUOD55HfsvFXNVQa_5TFRDibi9LsT7Sd_az0iGB0TfAb0v3ZR0qnmgyp5pTeIeU5UqhtbgU9RnUCVmGIK-SZYNvrlXgv9hiKAZGhLgeI8hO40utfT2YTYHgD2Aiufqo3RIbJA
代码javascript简单

Node.js JWT令牌创建与验证

使用jsonwebtoken库在Node.js中创建和验证JWT令牌

难度

2/10

预计时间

10 min

javascript
const jwt = require('jsonwebtoken');

// JWT Secret Key (store this securely!)
const SECRET_KEY = 'your-super-secret-key-change-in-production';

// User data to be included in token
const userPayload = {
  userId: '12345',
  email: '[email protected]',
  role: 'user'
};

// Create JWT Token
function createJWT(payload, expiresIn = '1h') {
  return jwt.sign(payload, SECRET_KEY, {
    expiresIn: expiresIn,
    algorithm: 'HS256',
    issuer: 'your-api.com',
    audience: 'your-app.com'
  });
}

// Verify JWT Token
function verifyJWT(token) {
  try {
    const decoded = jwt.verify(token, SECRET_KEY);
    console.log('Token is valid:', decoded);
    return decoded;
  } catch (error) {
    console.error('Token verification failed:', error.message);
    return null;
  }
}

// Decode JWT (without verification)
function decodeJWT(token) {
  const decoded = jwt.decode(token, { complete: true });
  console.log('Decoded token:', decoded);
  return decoded;
}

// Usage Examples
console.log('=== Creating JWT ===');
const token = createJWT(userPayload, '2h');
console.log('Generated Token:', token);

console.log('\n=== Verifying JWT ===');
const verified = verifyJWT(token);
console.log('Verified Payload:', verified);

console.log('\n=== Decoding JWT ===');
const decoded = decodeJWT(token);
console.log('Header:', decoded.header);
console.log('Payload:', decoded.payload);

// Check if token is expired
function isTokenExpired(decodedToken) {
  const now = Math.floor(Date.now() / 1000);
  return decodedToken.exp < now;
}

if (verified) {
  console.log('Is token expired?', isTokenExpired(verified));
}
代码javascript中等

浏览器端JWT处理

在浏览器中使用axios拦截器处理JWT令牌存储和自动添加

难度

3/10

预计时间

15 min

javascript
// JWT Token Management in Browser
class AuthManager {
  constructor() {
    this.tokenKey = 'jwt_token';
    this.refreshTokenKey = 'jwt_refresh_token';
  }

  // Store JWT token
  setToken(token, rememberMe = false) {
    const storage = rememberMe ? localStorage : sessionStorage;
    storage.setItem(this.tokenKey, token);
    
    // Also store expiration time
    const decoded = this.decodeToken(token);
    if (decoded && decoded.exp) {
      storage.setItem('jwt_expires_at', decoded.exp);
    }
  }

  // Get JWT token
  getToken() {
    return localStorage.getItem(this.tokenKey) || 
           sessionStorage.getItem(this.tokenKey);
  }

  // Remove JWT token
  removeToken() {
    localStorage.removeItem(this.tokenKey);
    sessionStorage.removeItem(this.tokenKey);
    localStorage.removeItem('jwt_expires_at');
    sessionStorage.removeItem('jwt_expires_at');
  }

  // Check if token is expired
  isTokenExpired() {
    const expiresAt = localStorage.getItem('jwt_expires_at') || 
                     sessionStorage.getItem('jwt_expires_at');
    if (!expiresAt) return true;
    
    return parseInt(expiresAt) < Math.floor(Date.now() / 1000);
  }

  // Decode token without verification
  decodeToken(token) {
    try {
      const payload = JSON.parse(atob(token.split('.')[1]));
      return payload;
    } catch (error) {
      return null;
    }
  }

  // Get user info from token
  getUserInfo() {
    const token = this.getToken();
    if (!token) return null;
    
    const decoded = this.decodeToken(token);
    return decoded;
  }
}

// Axios Interceptors for JWT
const authManager = new AuthManager();

// Request Interceptor - Add JWT token to every request
axios.interceptors.request.use(
  (config) => {
    const token = authManager.getToken();
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// Response Interceptor - Handle token expiration
axios.interceptors.response.use(
  (response) => response,
  async (error) => {
    const originalRequest = error.config;
    
    // If token expired and we haven't tried to refresh yet
    if (error.response?.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true;
      
      try {
        // Try to refresh token
        const newToken = await refreshToken();
        authManager.setToken(newToken);
        
        // Retry the original request with new token
        originalRequest.headers.Authorization = `Bearer ${newToken}`;
        return axios(originalRequest);
      } catch (refreshError) {
        // If refresh fails, redirect to login
        authManager.removeToken();
        window.location.href = '/login';
        return Promise.reject(refreshError);
      }
    }
    
    return Promise.reject(error);
  }
);

// Refresh token function
async function refreshToken() {
  const refreshToken = localStorage.getItem('jwt_refresh_token');
  if (!refreshToken) {
    throw new Error('No refresh token available');
  }
  
  const response = await axios.post('/api/auth/refresh', {
    refresh_token: refreshToken
  });
  
  return response.data.access_token;
}

// API Service with JWT
class ApiService {
  async login(email, password, rememberMe = false) {
    try {
      const response = await axios.post('/api/auth/login', {
        email,
        password
      });
      
      const { access_token, refresh_token } = response.data;
      authManager.setToken(access_token, rememberMe);
      localStorage.setItem('jwt_refresh_token', refresh_token);
      
      return response.data;
    } catch (error) {
      console.error('Login failed:', error);
      throw error;
    }
  }
  
  async logout() {
    try {
      await axios.post('/api/auth/logout');
    } catch (error) {
      console.error('Logout failed:', error);
    } finally {
      authManager.removeToken();
      localStorage.removeItem('jwt_refresh_token');
    }
  }
  
  async getProtectedData() {
    const response = await axios.get('/api/protected/data');
    return response.data;
  }
}

// Usage Example
const apiService = new ApiService();

// Login
// apiService.login('[email protected]', 'password123', true)
//   .then(() => console.log('Logged in successfully'))
//   .catch(error => console.error('Login failed:', error));

// Access protected data
// apiService.getProtectedData()
//   .then(data => console.log('Protected data:', data))
//   .catch(error => console.error('Access denied:', error));
代码javascript中等

Express.js JWT中间件

实现Express.js JWT认证中间件保护路由

难度

4/10

预计时间

20 min

javascript
const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');

const app = express();
app.use(express.json());

// JWT Configuration
const JWT_CONFIG = {
  SECRET: 'your-super-secret-key-change-in-production',
  ACCESS_TOKEN_EXPIRY: '15m',
  REFRESH_TOKEN_EXPIRY: '7d',
  ALGORITHM: 'HS256'
};

// Mock user database
const users = [
  {
    id: 1,
    email: '[email protected]',
    password: '$2a$10$N9qo8uLOickgx2ZMRZoMy.Mwrz2UqJ6H4f9G4UJ8T8K8W8j8jK8iK',
    role: 'admin'
  }
];

// JWT Middleware
const authenticateJWT = (req, res, next) => {
  const authHeader = req.headers.authorization;
  
  if (!authHeader) {
    return res.status(401).json({ message: 'Authorization header required' });
  }
  
  const token = authHeader.split(' ')[1]; // Bearer TOKEN
  
  try {
    const decoded = jwt.verify(token, JWT_CONFIG.SECRET);
    req.user = decoded;
    next();
  } catch (error) {
    if (error.name === 'TokenExpiredError') {
      return res.status(401).json({ message: 'Token expired' });
    } else if (error.name === 'JsonWebTokenError') {
      return res.status(401).json({ message: 'Invalid token' });
    } else {
      return res.status(500).json({ message: 'Internal server error' });
    }
  }
};

// Role-based Authorization Middleware
const authorize = (roles = []) => {
  return (req, res, next) => {
    if (!req.user) {
      return res.status(401).json({ message: 'Authentication required' });
    }
    
    if (roles.length && !roles.includes(req.user.role)) {
      return res.status(403).json({ message: 'Insufficient permissions' });
    }
    
    next();
  };
};

// Generate Access Token
const generateAccessToken = (user) => {
  return jwt.sign(
    { 
      userId: user.id, 
      email: user.email, 
      role: user.role 
    },
    JWT_CONFIG.SECRET,
    { 
      expiresIn: JWT_CONFIG.ACCESS_TOKEN_EXPIRY,
      algorithm: JWT_CONFIG.ALGORITHM,
      issuer: 'your-api.com',
      audience: 'your-app.com'
    }
  );
};

// Generate Refresh Token
const generateRefreshToken = (user) => {
  return jwt.sign(
    { 
      userId: user.id,
      tokenType: 'refresh'
    },
    JWT_CONFIG.SECRET,
    { 
      expiresIn: JWT_CONFIG.REFRESH_TOKEN_EXPIRY,
      algorithm: JWT_CONFIG.ALGORITHM
    }
  );
};

// Login Route
app.post('/api/auth/login', async (req, res) => {
  try {
    const { email, password } = req.body;
    
    // Find user
    const user = users.find(u => u.email === email);
    if (!user) {
      return res.status(401).json({ message: 'Invalid credentials' });
    }
    
    // Check password
    const isValidPassword = await bcrypt.compare(password, user.password);
    if (!isValidPassword) {
      return res.status(401).json({ message: 'Invalid credentials' });
    }
    
    // Generate tokens
    const accessToken = generateAccessToken(user);
    const refreshToken = generateRefreshToken(user);
    
    res.json({
      access_token: accessToken,
      refresh_token: refreshToken,
      user: {
        id: user.id,
        email: user.email,
        role: user.role
      }
    });
  } catch (error) {
    res.status(500).json({ message: 'Internal server error' });
  }
});

// Refresh Token Route
app.post('/api/auth/refresh', (req, res) => {
  try {
    const { refresh_token } = req.body;
    
    if (!refresh_token) {
      return res.status(400).json({ message: 'Refresh token required' });
    }
    
    const decoded = jwt.verify(refresh_token, JWT_CONFIG.SECRET);
    
    if (decoded.tokenType !== 'refresh') {
      return res.status(401).json({ message: 'Invalid refresh token' });
    }
    
    // Find user and generate new access token
    const user = users.find(u => u.id === decoded.userId);
    if (!user) {
      return res.status(401).json({ message: 'User not found' });
    }
    
    const newAccessToken = generateAccessToken(user);
    
    res.json({
      access_token: newAccessToken
    });
  } catch (error) {
    res.status(401).json({ message: 'Invalid refresh token' });
  }
});

// Protected Routes
app.get('/api/protected', authenticateJWT, (req, res) => {
  res.json({ 
    message: 'This is a protected route',
    user: req.user 
  });
});

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

// Logout Route
app.post('/api/auth/logout', authenticateJWT, (req, res) => {
  // In a real app, you might want to blacklist the token
  res.json({ message: 'Logged out successfully' });
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});
代码javascript复杂

JWT安全最佳实践

使用非对称加密实现高级JWT安全配置

难度

5/10

预计时间

30 min

javascript
const jwt = require('jsonwebtoken');
const crypto = require('crypto');

// Advanced JWT Security Implementation
class JWTSecurityManager {
  constructor(config) {
    const generatedKeyPair = this.generateKeyPair();
    this.config = {
      // Use asymmetric keys for better security
      publicKey: config.publicKey || generatedKeyPair.publicKey,
      privateKey: config.privateKey || generatedKeyPair.privateKey,
      
      // Token configuration
      accessTokenExpiry: config.accessTokenExpiry || '15m',
      refreshTokenExpiry: config.refreshTokenExpiry || '7d',
      issuer: config.issuer || 'your-api.com',
      audience: config.audience || 'your-app.com',
      
      // Security settings
      algorithm: 'RS256', // Use RSA for asymmetric encryption
      keyRotationInterval: config.keyRotationInterval || 86400000, // 24 hours
      maxTokenAge: config.maxTokenAge || 3600000, // 1 hour
      
      // Blacklist configuration
      blacklistType: config.blacklistType || 'memory', // 'redis' or 'memory'
      redisConfig: config.redisConfig || { host: 'localhost', port: 6379 }
    };
    
    this.blacklist = new Map();
    this.currentKeyId = this.generateKeyId();
    this.keys = new Map([[this.currentKeyId, this.config.publicKey]]);
  }
  
  // Generate RSA key pair
  generateKeyPair() {
    const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
      modulusLength: 2048,
      publicKeyEncoding: {
        type: 'spki',
        format: 'pem'
      },
      privateKeyEncoding: {
        type: 'pkcs8',
        format: 'pem'
      }
    });
    return { publicKey, privateKey };
  }
  
  // Generate unique key ID
  generateKeyId() {
    return `key-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
  }
  
  // Rotate keys
  rotateKeys() {
    const oldKeyId = this.currentKeyId;
    const newKeyId = this.generateKeyId();
    const newKeyPair = this.generateKeyPair();
    
    this.keys.set(newKeyId, newKeyPair.publicKey);
    this.config.privateKey = newKeyPair.privateKey;
    this.config.publicKey = newKeyPair.publicKey;
    
    // Keep old keys for 1 hour to validate existing tokens
    setTimeout(() => {
      this.keys.delete(oldKeyId);
    }, 3600000);
    
    this.currentKeyId = newKeyId;
    return newKeyId;
  }
  
  // Add token to blacklist
  async addToBlacklist(token, expiryTime) {
    const tokenId = this.getTokenId(token);
    const expiry = expiryTime || this.getTokenExpiry(token);
    
    if (this.config.blacklistType === 'redis') {
      // Redis implementation for distributed systems
      await this.redis.setex(`jwt:blacklist:${tokenId}`, expiry, '1');
    } else {
      // In-memory blacklist for single instance
      this.blacklist.set(tokenId, Date.now() + (expiry * 1000));
    }
  }
  
  // Check if token is blacklisted
  async isBlacklisted(token) {
    const tokenId = this.getTokenId(token);
    
    if (this.config.blacklistType === 'redis') {
      const result = await this.redis.get(`jwt:blacklist:${tokenId}`);
      return !!result;
    } else {
      const expiry = this.blacklist.get(tokenId);
      return expiry && expiry > Date.now();
    }
  }
  
  // Extract token ID (jti claim)
  getTokenId(token) {
    const decoded = jwt.decode(token);
    return decoded.jti;
  }
  
  // Get token expiry
  getTokenExpiry(token) {
    const decoded = jwt.decode(token);
    return decoded.exp - Math.floor(Date.now() / 1000);
  }
  
  // Create JWT with enhanced security
  async createToken(payload, options = {}) {
    const tokenId = crypto.randomBytes(16).toString('hex');
    const keyId = this.currentKeyId;
    
    const enhancedPayload = {
      ...payload,
      jti: tokenId, // JWT ID for blacklisting
      iat: Math.floor(Date.now() / 1000),
      iss: this.config.issuer,
      aud: this.config.audience
    };
    
    const tokenOptions = {
      algorithm: this.config.algorithm,
      expiresIn: options.expiresIn || this.config.accessTokenExpiry,
      keyid: keyId
    };
    
    return jwt.sign(enhancedPayload, this.config.privateKey, tokenOptions);
  }
  
  // Verify JWT with enhanced security checks
  async verifyToken(token) {
    try {
      // Check blacklist first
      if (await this.isBlacklisted(token)) {
        throw new Error('Token has been revoked');
      }
      
      // Decode token to get key ID
      const decoded = jwt.decode(token, { complete: true });
      if (!decoded || !decoded.header || !decoded.header.kid) {
        throw new Error('Invalid token structure');
      }
      const keyId = decoded.header.kid;
      
      // Verify the token hasn't been tampered with
      const key = this.keys.get(keyId);
      if (!key) {
        throw new Error('Invalid key ID');
      }
      
      // Verify token signature and claims
      const verified = jwt.verify(token, key, {
        algorithms: [this.config.algorithm],
        issuer: this.config.issuer,
        audience: this.config.audience,
        maxAge: this.config.maxTokenAge
      });
      
      // Additional security checks
      if (verified.iat > Math.floor(Date.now() / 1000)) {
        throw new Error('Token issued in the future');
      }
      
      if (verified.exp - verified.iat > this.config.maxTokenAge / 1000) {
        throw new Error('Token validity period exceeds maximum allowed');
      }
      
      return verified;
    } catch (error) {
      console.error('Token verification failed:', error.message);
      throw error;
    }
  }
  
  // Middleware for Express.js
  middleware() {
    return async (req, res, next) => {
      try {
        const authHeader = req.headers.authorization;
        
        if (!authHeader || !authHeader.startsWith('Bearer ')) {
          return res.status(401).json({ error: 'Authorization header required' });
        }
        
        const token = authHeader.substring(7);
        const decoded = await this.verifyToken(token);
        
        req.user = decoded;
        req.token = token;
        
        next();
      } catch (error) {
        return res.status(401).json({ 
          error: 'Invalid or expired token',
          details: error.message 
        });
      }
    };
  }
  
  // Rate limiting middleware
  rateLimitMiddleware(maxAttempts = 5, windowMs = 900000) {
    const attempts = new Map();
    
    return async (req, res, next) => {
      const ip = req.ip || req.connection.remoteAddress;
      const now = Date.now();
      
      if (!attempts.has(ip)) {
        attempts.set(ip, []);
      }
      
      const userAttempts = attempts.get(ip);
      const validAttempts = userAttempts.filter(time => now - time < windowMs);
      
      if (validAttempts.length >= maxAttempts) {
        return res.status(429).json({ error: 'Too many attempts' });
      }
      
      validAttempts.push(now);
      attempts.set(ip, validAttempts);
      
      next();
    };
  }
}

// Usage Example
const jwtManager = new JWTSecurityManager({
  issuer: 'your-api.com',
  audience: 'your-app.com',
  accessTokenExpiry: '15m',
  refreshTokenExpiry: '7d'
});

// Apply to Express app
const express = require('express');
const app = express();

// Security middleware stack
app.use('/api/*', [
  jwtManager.rateLimitMiddleware(),
  jwtManager.middleware()
]);

// Protected route
app.get('/api/protected', (req, res) => {
  res.json({ 
    message: 'Secure access granted',
    user: req.user 
  });
});

// Logout route
app.post('/api/logout', async (req, res) => {
  try {
    await jwtManager.addToBlacklist(req.token);
    res.json({ message: 'Logged out successfully' });
  } catch (error) {
    res.status(500).json({ error: 'Logout failed' });
  }
});
代码javascript复杂

JWT测试

为JWT功能编写单元测试和集成测试

难度

4/10

预计时间

25 min

javascript
const jwt = require('jsonwebtoken');
const { expect } = require('chai');
const sinon = require('sinon');
const JWTSecurityManager = require('./jwt-security-manager');

describe('JWT Implementation Tests', () => {
  let jwtManager;
  const testConfig = {
    issuer: 'test-api.com',
    audience: 'test-app.com',
    accessTokenExpiry: '1h',
    refreshTokenExpiry: '7d',
    algorithm: 'HS256'
  };
  
  beforeEach(() => {
    jwtManager = new JWTSecurityManager(testConfig);
  });
  
  describe('Token Creation', () => {
    it('should create a valid JWT token', () => {
      const payload = { userId: 123, email: '[email protected]' };
      const token = jwtManager.createToken(payload);
      
      expect(token).to.be.a('string');
      expect(token.split('.')).to.have.lengthOf(3);
    });
    
    it('should include required claims', () => {
      const payload = { userId: 123 };
      const token = jwtManager.createToken(payload);
      const decoded = jwt.decode(token);
      
      expect(decoded).to.have.property('iat');
      expect(decoded).to.have.property('iss', testConfig.issuer);
      expect(decoded).to.have.property('aud', testConfig.audience);
      expect(decoded).to.have.property('jti');
      expect(decoded).to.have.property('userId', 123);
    });
  });
  
  describe('Token Verification', () => {
    it('should verify a valid token', async () => {
      const payload = { userId: 123, email: '[email protected]' };
      const token = jwtManager.createToken(payload);
      
      const verified = await jwtManager.verifyToken(token);
      expect(verified).to.have.property('userId', 123);
      expect(verified).to.have.property('email', '[email protected]');
    });
    
    it('should reject expired tokens', async () => {
      const payload = { userId: 123 };
      const token = jwtManager.createToken(payload, { expiresIn: '-1s' });
      
      try {
        await jwtManager.verifyToken(token);
        expect.fail('Should have thrown error for expired token');
      } catch (error) {
        expect(error.message).to.include('expired');
      }
    });
    
    it('should reject tokens with invalid signature', async () => {
      const payload = { userId: 123 };
      const token = jwtManager.createToken(payload);
      const tamperedToken = token + 'tampered';
      
      try {
        await jwtManager.verifyToken(tamperedToken);
        expect.fail('Should have thrown error for invalid signature');
      } catch (error) {
        expect(error.message).to.include('invalid signature');
      }
    });
  });
  
  describe('Token Blacklisting', () => {
    it('should blacklist and reject tokens', async () => {
      const payload = { userId: 123 };
      const token = jwtManager.createToken(payload);
      
      // Token should be valid initially
      let verified = await jwtManager.verifyToken(token);
      expect(verified).to.exist;
      
      // Blacklist the token
      await jwtManager.addToBlacklist(token);
      
      // Token should now be rejected
      try {
        await jwtManager.verifyToken(token);
        expect.fail('Should have thrown error for blacklisted token');
      } catch (error) {
        expect(error.message).to.include('revoked');
      }
    });
  });
  
  describe('Middleware Integration', () => {
    let req, res, next;
    
    beforeEach(() => {
      req = {
        headers: {},
        ip: '127.0.0.1'
      };
      res = {
        status: sinon.stub().returnsThis(),
        json: sinon.stub()
      };
      next = sinon.stub();
    });
    
    it('should pass with valid token', async () => {
      const payload = { userId: 123 };
      const token = jwtManager.createToken(payload);
      req.headers.authorization = `Bearer ${token}`;
      
      const middleware = jwtManager.middleware();
      await middleware(req, res, next);
      
      expect(next.calledOnce).to.be.true;
      expect(req.user).to.have.property('userId', 123);
    });
    
    it('should reject missing authorization header', async () => {
      const middleware = jwtManager.middleware();
      await middleware(req, res, next);
      
      expect(next.called).to.be.false;
      expect(res.status.calledWith(401)).to.be.true;
      expect(res.json.calledWith({ error: 'Authorization header required' })).to.be.true;
    });
    
    it('should reject invalid token format', async () => {
      req.headers.authorization = 'InvalidTokenFormat';
      
      const middleware = jwtManager.middleware();
      await middleware(req, res, next);
      
      expect(next.called).to.be.false;
      expect(res.status.calledWith(401)).to.be.true;
    });
  });
  
  describe('Key Rotation', () => {
    it('should rotate keys successfully', () => {
      const originalKeyId = jwtManager.currentKeyId;
      const newKeyId = jwtManager.rotateKeys();
      
      expect(newKeyId).to.not.equal(originalKeyId);
      expect(jwtManager.keys.has(originalKeyId)).to.be.true;
      expect(jwtManager.keys.has(newKeyId)).to.be.true;
    });
    
    it('should verify tokens created with old keys', async () => {
      const originalKeyId = jwtManager.currentKeyId;
      const payload = { userId: 123 };
      const token = jwtManager.createToken(payload);
      
      // Rotate keys
      jwtManager.rotateKeys();
      
      // Old token should still be valid
      const verified = await jwtManager.verifyToken(token);
      expect(verified).to.have.property('userId', 123);
    });
  });
});

describe('JWT Security Vulnerabilities', () => {
  it('should prevent algorithm confusion attacks', async () => {
    // Create a token with 'none' algorithm
    const maliciousToken = jwt.sign(
      { userId: 'admin', isAdmin: true },
      'any-secret',
      { algorithm: 'none' }
    );
    
    try {
      await jwtManager.verifyToken(maliciousToken);
      expect.fail('Should have rejected algorithm none');
    } catch (error) {
      expect(error.message).to.not.include('admin');
    }
  });
  
  it('should prevent token replay attacks', async () => {
    const payload = { userId: 123 };
    const token = jwtManager.createToken(payload);
    
    // First verification should succeed
    await jwtManager.verifyToken(token);
    
    // Blacklist the token
    await jwtManager.addToBlacklist(token);
    
    // Second verification should fail
    try {
      await jwtManager.verifyToken(token);
      expect.fail('Should have prevented replay attack');
    } catch (error) {
      expect(error.message).to.include('revoked');
    }
  });
});

// Performance Tests
describe('JWT Performance', () => {
  it('should handle token creation under 10ms', () => {
    const payload = { userId: 123, email: '[email protected]' };
    const start = Date.now();
    
    for (let i = 0; i < 1000; i++) {
      jwtManager.createToken(payload);
    }
    
    const duration = Date.now() - start;
    const avgTime = duration / 1000;
    
    console.log(`Average token creation time: ${avgTime}ms`);
    expect(avgTime).to.be.lessThan(10);
  });
  
  it('should handle token verification under 5ms', async () => {
    const payload = { userId: 123, email: '[email protected]' };
    const token = jwtManager.createToken(payload);
    
    const start = Date.now();
    
    for (let i = 0; i < 1000; i++) {
      await jwtManager.verifyToken(token);
    }
    
    const duration = Date.now() - start;
    const avgTime = duration / 1000;
    
    console.log(`Average token verification time: ${avgTime}ms`);
    expect(avgTime).to.be.lessThan(5);
  });
});

// Integration Tests
describe('JWT Integration Tests', () => {
  let app, server;
  
  before(() => {
    const express = require('express');
    app = express();
    app.use(express.json());
    
    // Apply JWT middleware
    app.use('/api/*', jwtManager.middleware());
    
    app.get('/api/test', (req, res) => {
      res.json({ user: req.user });
    });
    
    server = app.listen(0); // Random available port
  });
  
  after(() => {
    server.close();
  });
  
  it('should integrate with Express.js successfully', async () => {
    const payload = { userId: 123, email: '[email protected]' };
    const token = jwtManager.createToken(payload);
    
    const response = await fetch(`http://localhost:${server.address().port}/api/test`, {
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });
    
    const data = await response.json();
    expect(data.user).to.have.property('userId', 123);
  });
});

工具

经常与该案例搭配使用的工具

相关内容

相关案例集合

相关内容

相关专题

工具使用指南

帮助搜索与理解工作流的案例说明

标题

JWT 示例

描述

从基础令牌结构到高级安全实现的全面JWT示例

概览

从基础令牌结构到高级安全实现的全面JWT示例

适用场景

  • Use this sample set when you want reference inputs for JWT 示例.
  • Use it to preview output formats and compare related sample variants.

使用方式

  1. 1Open a sample entry to inspect the prepared example payload or asset.
  2. 2Compare it with related tools to understand how the workflow connects.

常见用途

  • JWT令牌
  • Node.js JWT令牌创建与验证
  • 浏览器端JWT处理
  • Express.js JWT中间件
  • JWT安全最佳实践
  • JWT测试

常见问题

What is included in JWT 示例?

This page includes curated sample entries, related tools, and neighboring sample collections for JWT 示例.

专题

JWT 构造与安全审查

生成受控 JWT 测试样本或检查已获授权的样本,审查 Claim、算法、过期状态、敏感字段和签名证据,并明确解码不等于验签。

专题

凭据与 JWT 安全检查工作流

生成或验证密码凭据,检查 JWT 结构与安全信号,并明确区分私钥对与密码工具。

专题

获授权 JWT、OTP、TOTP 与会话测试工作流

准备脱敏认证 fixture,区分令牌生成、解码与校验,测试 OTP/TOTP 的时间行为,并在不暴露真实密钥的前提下审计 JWT 与会话证据。

专题

药代动力学教学模型与结果核查

用于教学或 QA 的药代公式、模型假设和结果一致性核查,不提供用药剂量、诊断或临床建议。

首页
工具3201
案例593
可视化465
文件查看器103
专题233
标签333
图像、音频与视频657

图像、音频、视频处理、转换与优化工具

数学、日期与金融644

计算器、数值计算、日期逻辑、统计与金融工具

设计与颜色297

颜色、版式、图形、视觉样式与设计辅助工具

文本与写作209

写作、清洗、格式化、提取与文本分析工具

开发与 Web193

开发者工具、网络处理、Web 调试与自动化辅助工具

转换与编码175

格式、文件、压缩包、单位与编码转换工具

FLAC/WAV 无损音源疑点筛查与证据交付
自托管抽奖组件配置复核、嵌入测试与上线交付
Stripe 优惠码候选批次审核与本地导入预检
批量照片技术初筛、近重复复核与修图候选交付
界面截图结构化、人工校对与开发交付

© 2026 Elysia Tools. 保留所有权利。

文档价格关于我们服务条款隐私政策Cookie 政策联系我们

Security

JWT令牌生成器

生成带有自定义声明和算法的JWT令牌

Security

JWT 解码器

解码 JWT 令牌

Security

JWT 解析与签名验证器

解析 JWT 的 header/payload 并高亮显示,诊断 exp/nbf/iat/iss/aud/sub/jti 等 claim,使用 HS*/RS*/PS*/ES*/EdDSA 密钥验签,并提供篡改 payload 的伪造教学演示

Security

CSV/JSON 数据水印器

为 CSV 或 JSON 导出注入可见或签名式水印字段,以便后续追踪共享数据

Data Processing

JSON键提取器

从JSON对象中提取所有键,支持多种输出格式。非常适合分析JSON结构、生成文档和理解复杂的嵌套对象。

Security

AGEX 包元信息脱敏器

在不改动密文字节的前提下,重写 AGEX 包中可暴露的文件名、MIME 类型或 signer ID

Data Analysis

数据质量画像师

对 CSV 或 JSON 数据集进行质量画像,识别缺失值、重复行、格式漂移、类型推断和数值异常。

Design

ECharts 主题 Token 抽取器

从 ECharts 主题 JSON 抽取设计 token——颜色、数字、字号与字符串——并直接导出到你的设计系统。粘贴一个主题对象(即通过 echarts.init(dom, themeName) 注册的那种),工具遍历每个叶子节点,为每个颜色(可选地将命名色/rgb 规范化为 hex)、间距数字、字号与字符串打标,然后输出干净的 CSS 变量、Tailwind theme.extend 配置、Style Dictionary tokens.json 或 SCSS 变量。在 ECharts 可视化主题与 Figma/CSS/Tailwind 设计 token 之间架桥,无需逐个手抄。

文档文件

PDF示例

2026-02-01 到 2026-02-10 工具生成的PDF示例

Go

Web Go 数据序列化示例

Web Go 数据序列化示例,包括JSON编码/解码和XML解析

Python

Web Python 数据序列化示例

Web Python 数据序列化示例,包括JSON和XML处理

Rust

Web Rust 数据序列化示例

Web Rust 数据序列化示例,包括JSON序列化、反序列化和XML解析

TypeScript

Web TypeScript 数据序列化示例

Web TypeScript 数据序列化示例,包括JSON序列化/反序列化和XML解析

可观测性

分布式追踪示例

使用 Jaeger、OpenTelemetry 和其他现代可观测性工具的综合分布式追踪示例,适用于微服务架构