TypeScript 中的 JWT 令牌:JSON Web Tokens 完全指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

TypeScript 中的 JWT 令牌:完全指南



JSON Web Token (JWT) 是一种基于 JSON 格式创建访问令牌的开放标准 (RFC 7519)。JWT 广泛用于客户端和服务器之间的身份验证和信息交换。在本文中,我们将详细讲解如何使用流行的库和最佳实践在 TypeScript 中处理 JWT 令牌。



什么是 JWT?



JWT 由三部分组成,各部分之间用点分隔:

  • Header(头部) — 包含令牌类型和签名算法的信息
  • Payload(载荷) — 包含数据(声明),如用户 ID、角色、过期时间
  • Signature(签名) — 由头部、载荷和密钥生成


典型的 JWT 如下所示:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c


安装 TypeScript 中处理 JWT 的库



为了在 TypeScript 中处理 JWT,我们将使用 jsonwebtoken 库及其类型定义 @types/jsonwebtoken。



npm install jsonwebtokennpm install --save-dev @types/jsonwebtoken


在 TypeScript 中创建 JWT 令牌



让我们看一个使用类型化载荷创建 JWT 令牌的示例:



import jwt from 'jsonwebtoken';

// 定义载荷的接口interface TokenPayload { userId: string; email: string; role: 'user' | 'admin';}

// 密钥(在实际项目中请存储在 .env 文件中)const JWT_SECRET = 'your-super-secret-key';

// 创建令牌function generateToken(payload: TokenPayload): string { return jwt.sign(payload, JWT_SECRET, { expiresIn: '1h', // 令牌有效期为 1 小时 issuer: 'pythonlib.ru', subject: payload.userId });}

// 使用示例const userPayload: TokenPayload = { userId: '12345', email: 'user@example.com', role: 'user'};

const token = generateToken(userPayload);console.log('生成的令牌:', token);


JWT 的验证和解码



使用以下代码验证令牌的真实性并提取数据:



import jwt, { JwtPayload, VerifyErrors } from 'jsonwebtoken';

interface DecodedToken extends JwtPayload { userId: string; email: string; role: 'user' | 'admin';}

function verifyToken(token: string): DecodedToken | null { try { const decoded = jwt.verify(token, JWT_SECRET) as DecodedToken; return decoded; } catch (error) { if (error instanceof jwt.TokenExpiredError) { console.error('令牌已过期'); } else if (error instanceof jwt.JsonWebTokenError) { console.error('无效的令牌'); } else { console.error('验证错误:', error); } return null; }}

// 验证令牌const decoded = verifyToken(token);if (decoded) { console.log('令牌数据:', decoded); console.log('用户角色:', decoded.role);}


Express.js 的中间件(TypeScript)



将 JWT 验证集成到具有完整类型定义的 Express 中间件中:



import { Request, Response, NextFunction } from 'express';import jwt from 'jsonwebtoken';

// 扩展 Request 接口以存储用户数据interface AuthRequest extends Request { user?: { userId: string; email: string; role: 'user' | 'admin'; };}

function authMiddleware(req: AuthRequest, res: Response, next: NextFunction): void { const authHeader = req.headers.authorization;

if (!authHeader || !authHeader.startsWith('Bearer ')) { res.status(401).json({ message: '未提供令牌' }); return; }

const token = authHeader.split(' ')[1];

try { const decoded = jwt.verify(token, JWT_SECRET) as DecodedToken; req.user = { userId: decoded.userId, email: decoded.email, role: decoded.role }; next(); } catch (error) { if (error instanceof jwt.TokenExpiredError) { res.status(401).json({ message: '令牌已过期' }); } else { res.status(401).json({ message: '无效的令牌' }); } }}


最佳实践



  • 始终将密钥存储在环境变量中,而不是代码中
  • 为令牌设置合理的过期时间(例如 15 分钟到 1 小时)
  • 使用 HTTPS 传输令牌
  • 不要在令牌中存储敏感数据(如密码)
  • 实现令牌刷新机制


总结



JWT 令牌是构建现代 Web 应用程序身份验证的强大工具。在 TypeScript 中使用它们可以确保类型安全并减少运行时错误。使用 jsonwebtoken 库,您可以轻松创建、验证和解码令牌,而类型定义则有助于在开发阶段捕获错误。



请记住,安全始终是首要任务:保护您的密钥,使用 HTTPS,并遵循最佳实践来保护您的应用程序和用户数据。

推荐