乐闻世界logo
搜索文章和话题

如何优化 JWT 的性能

2026年2月21日 17:52

JWT 的性能优化对于高并发系统非常重要。以下是主要的优化策略和实现方法:

1. 签名算法优化

选择更快的算法

javascript
// ES256 比 RS256 更快,签名更小 const jwt = require('jsonwebtoken'); // 使用 ES256 (ECDSA) const token = jwt.sign(payload, privateKey, { algorithm: 'ES256' // 比 RS256 快约 2-3 倍 }); // HS256 最快,但需要安全地管理密钥 const token = jwt.sign(payload, secretKey, { algorithm: 'HS256' // 最快,但密钥管理复杂 });

算法性能对比

算法签名速度验证速度签名大小推荐场景
HS256⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐~32B单体应用
RS256⭐⭐⭐⭐⭐~256B分布式系统
ES256⭐⭐⭐⭐⭐⭐⭐~64B移动应用

2. 缓存优化

验证结果缓存

javascript
const NodeCache = require('node-cache'); const tokenCache = new NodeCache({ stdTTL: 300, // 5分钟缓存 checkperiod: 60 }); function verifyTokenCached(token) { const cacheKey = `token:${token}`; // 检查缓存 const cached = tokenCache.get(cacheKey); if (cached) { return cached; } // 验证 token const decoded = jwt.verify(token, SECRET_KEY); // 缓存结果 tokenCache.set(cacheKey, decoded); return decoded; } // 使用示例 app.get('/api/data', (req, res) => { const token = req.headers['authorization']?.replace('Bearer ', ''); const decoded = verifyTokenCached(token); // 使用缓存 res.json({ data: '...' }); });

公钥缓存

javascript
const jose = require('node-jose'); let cachedKeyStore = null; let cacheExpiry = 0; async function getKeyStore() { if (cachedKeyStore && Date.now() < cacheExpiry) { return cachedKeyStore; } // 从远程获取 JWK Set const response = await fetch('https://auth.example.com/.well-known/jwks.json'); const jwks = await response.json(); // 创建 keystore const keystore = await jose.JWK.createKeyStore(); for (const jwk of jwks.keys) { await keystore.add(jwk); } cachedKeyStore = keystore; cacheExpiry = Date.now() + (5 * 60 * 1000); // 5分钟 return keystore; }

3. Token 大小优化

减少 Payload 大小

javascript
// ❌ 不好的做法:字段名过长 const token = jwt.sign({ userId: '1234567890', userName: 'john.doe@example.com', userRole: 'administrator', userPermissions: ['read', 'write', 'delete'] }, SECRET_KEY); // ✅ 好的做法:使用短字段名 const token = jwt.sign({ uid: '1234567890', // userId -> uid unm: 'john.doe@example.com', // userName -> unm rol: 'admin', // userRole -> rol prms: ['r', 'w', 'd'] // userPermissions -> prms }, SECRET_KEY); // ✅ 更好的做法:只存储 ID,其他信息从数据库获取 const token = jwt.sign({ uid: '1234567890' }, SECRET_KEY);

使用压缩

javascript
const { deflate, inflate } = require('pako'); function compressPayload(payload) { const json = JSON.stringify(payload); const compressed = deflate(json); return compressed.toString('base64'); } function decompressPayload(compressed) { const buffer = Buffer.from(compressed, 'base64'); const decompressed = inflate(buffer); return JSON.parse(decompressed.toString()); } // 使用示例 const payload = { uid: '123', unm: 'john', rol: 'admin' }; const compressed = compressPayload(payload); const token = jwt.sign({ data: compressed }, SECRET_KEY);

4. 异步验证

使用异步 API

javascript
// ❌ 同步验证(阻塞) app.get('/api/data', (req, res) => { const token = req.headers['authorization']?.replace('Bearer ', ''); const decoded = jwt.verify(token, SECRET_KEY); // 阻塞 res.json({ data: '...' }); }); // ✅ 异步验证(非阻塞) app.get('/api/data', async (req, res) => { const token = req.headers['authorization']?.replace('Bearer ', ''); try { const decoded = await verifyTokenAsync(token); res.json({ data: '...' }); } catch (error) { res.status(401).json({ error: 'Invalid token' }); } }); // 异步验证函数 function verifyTokenAsync(token) { return new Promise((resolve, reject) => { jwt.verify(token, SECRET_KEY, (err, decoded) => { if (err) { reject(err); } else { resolve(decoded); } }); }); }

5. 批量验证

批量验证多个 Token

javascript
function verifyTokensBatch(tokens) { return tokens.map(token => { try { const decoded = jwt.verify(token, SECRET_KEY); return { token, valid: true, decoded }; } catch (error) { return { token, valid: false, error: error.message }; } }); } // 使用示例 const tokens = ['token1', 'token2', 'token3']; const results = verifyTokensBatch(tokens); const validTokens = results.filter(r => r.valid);

6. 数据库优化

减少数据库查询

javascript
// ❌ 每次请求都查询数据库 app.get('/api/user', async (req, res) => { const decoded = jwt.verify(token, SECRET_KEY); const user = await db.query('SELECT * FROM users WHERE id = ?', [decoded.userId]); res.json(user); }); // ✅ 使用 Redis 缓存用户信息 const redis = require('redis'); const client = redis.createClient(); app.get('/api/user', async (req, res) => { const decoded = jwt.verify(token, SECRET_KEY); // 先从缓存获取 let user = await client.get(`user:${decoded.userId}`); if (!user) { // 缓存未命中,查询数据库 user = await db.query('SELECT * FROM users WHERE id = ?', [decoded.userId]); // 存入缓存 await client.setex(`user:${decoded.userId}`, 300, JSON.stringify(user)); } else { user = JSON.parse(user); } res.json(user); });

7. 连接池优化

使用连接池

javascript
const mysql = require('mysql2/promise'); // 创建连接池 const pool = mysql.createPool({ host: 'localhost', user: 'root', password: 'password', database: 'mydb', waitForConnections: true, connectionLimit: 10, // 连接池大小 queueLimit: 0 }); app.get('/api/data', async (req, res) => { const decoded = jwt.verify(token, SECRET_KEY); // 使用连接池 const [rows] = await pool.query('SELECT * FROM data WHERE user_id = ?', [decoded.userId]); res.json(rows); });

8. 负载均衡

多实例部署

javascript
// 使用 Redis 共享缓存 const redis = require('redis'); const client = redis.createClient({ host: 'redis-server', port: 6379 }); // 所有实例共享同一个 Redis 缓存 function verifyTokenCached(token) { return new Promise(async (resolve, reject) => { const cacheKey = `token:${token}`; // 从 Redis 获取缓存 const cached = await client.get(cacheKey); if (cached) { return resolve(JSON.parse(cached)); } // 验证 token const decoded = jwt.verify(token, SECRET_KEY); // 存入 Redis await client.setex(cacheKey, 300, JSON.stringify(decoded)); resolve(decoded); }); }

9. 监控和调优

性能监控

javascript
const promClient = require('prom-client'); // 创建指标 const tokenVerifyDuration = new promClient.Histogram({ name: 'token_verify_duration_seconds', help: 'Token verification duration in seconds', buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1] }); const tokenCacheHits = new promClient.Counter({ name: 'token_cache_hits_total', help: 'Total number of token cache hits' }); const tokenCacheMisses = new prom.Client.Counter({ name: 'token_cache_misses_total', help: 'Total number of token cache misses' }); // 监控验证性能 function verifyTokenWithMetrics(token) { const end = tokenVerifyDuration.startTimer(); try { const decoded = verifyTokenCached(token); tokenCacheHits.inc(); return decoded; } catch (error) { tokenCacheMisses.inc(); throw error; } finally { end(); } } // 指标端点 app.get('/metrics', (req, res) => { res.set('Content-Type', promClient.register.contentType); res.end(promClient.register.metrics()); });

10. 最佳实践总结

性能优化清单

  • 使用更快的签名算法(ES256)
  • 实现验证结果缓存
  • 减少 Payload 大小
  • 使用异步验证
  • 批量验证多个 Token
  • 减少数据库查询
  • 使用连接池
  • 实现负载均衡
  • 添加性能监控
  • 定期分析和优化

性能基准测试

javascript
const Benchmark = require('benchmark'); const suite = new Benchmark.Suite; suite .add('HS256', () => { jwt.sign(payload, secretKey, { algorithm: 'HS256' }); }) .add('RS256', () => { jwt.sign(payload, privateKey, { algorithm: 'RS256' }); }) .add('ES256', () => { jwt.sign(payload, privateKey, { algorithm: 'ES256' }); }) .on('cycle', (event) => { console.log(String(event.target)); }) .run();

通过以上优化策略,可以显著提升 JWT 认证系统的性能,支持更高的并发量。

标签:JWT