跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
编程语言Node.js大前端

JWT(JSON Web Token)详解

JWT(JSON Web Token)是一种用于在各方之间安全传输信息的开放标准。它由 Header、Payload 和 Signature 三部分组成,具有无状态、自包含和跨域友好的特点。 JWT 的工作原理、结构组成、优势劣势及适用场景,涵盖了身份验证、单点登录等常见用例。同时提供了 Node.js、Python 和前端 JavaScript 的代码示例,阐述了密钥管理、存储安全、令牌过期处理等安全考量与最佳实践,帮助开发者在微服务和分布式架构中有效实施 JWT 认证方案。

moshang发布于 2026/2/28更新于 2026/10/24107 浏览

JWT(JSON Web Token)详解

什么是 JWT

JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在各方之间安全地传输信息。JWT 是一个紧凑的、URL 安全的令牌,通常用于身份验证和信息交换。

核心特点
  • 自包含:JWT 包含所有必要的信息,无需在服务器端存储会话信息
  • 无状态:服务器不需要存储用户状态,适合分布式系统
  • 跨域友好:可以在不同域名之间传递
  • 标准化:基于 RFC 7519 标准,有良好的生态系统支持

JWT 的结构

JWT 由三部分组成,用点(.)分隔:

Header.Payload.Signature 
1. Header(头部)

包含令牌类型和签名算法信息:

{"alg":"HS256","typ":"JWT"}
  • alg:签名算法(如 HS256、RS256 等)
  • typ:令牌类型,通常为 "JWT"
2. Payload(载荷)

包含声明(claims),有三种类型:

标准声明(Registered Claims)
  • iss(issuer):签发者
  • sub(subject):主题
  • aud(audience):受众
  • exp(expiration time):过期时间
  • nbf(not before):生效时间
  • iat(issued at):签发时间
  • jti(JWT ID):JWT 唯一标识
公共声明(Public Claims)

可以自定义,但需要避免冲突

私有声明(Private Claims)

自定义的声明,用于在同意使用它们的各方之间共享信息

示例 Payload:

{"sub":"1234567890","name"
:
"John Doe"
,
"iat"
:
1516239022
,
"exp"
:
1516242622
,
"role"
:
"admin"
}
3. Signature(签名)

用于验证令牌的完整性和真实性:

HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret ) 

JWT 的工作原理

认证流程
  1. 用户登录:用户提供凭据(用户名/密码)
  2. 验证凭据:服务器验证用户身份
  3. 生成 JWT:服务器生成包含用户信息的 JWT
  4. 返回令牌:将 JWT 返回给客户端
  5. 存储令牌:客户端存储 JWT(通常存储在 localStorage 或 cookie 中)
  6. 发送请求:客户端在后续请求中携带 JWT
  7. 验证令牌:服务器验证 JWT 的有效性
  8. 返回资源:验证通过后返回请求的资源
流程图
客户端 服务器 | | |-- 1. 登录请求 --------->| | |-- 2. 验证凭据 | |-- 3. 生成 JWT |<-- 4. 返回 JWT ---------| | | |-- 5. 携带 JWT 请求 ------>| | |-- 6. 验证 JWT |<-- 7. 返回资源 ---------| 

JWT 的优势与劣势

优势
  1. 无状态:服务器不需要存储会话信息
  2. 可扩展:适合微服务和分布式架构
  3. 跨域支持:可以在不同域名间使用
  4. 自包含:包含所有必要信息
  5. 标准化:基于开放标准,有良好的工具支持
劣势
  1. 令牌大小:比 session ID 大
  2. 无法撤销:在过期前无法主动失效
  3. 安全风险:如果密钥泄露,所有令牌都可能被伪造
  4. 性能考虑:每次请求都需要验证签名

JWT 的使用场景

1. 身份验证

最常见的用途,用于替代传统的 session-based 认证

2. 信息交换

在各方之间安全地传输信息

3. 单点登录(SSO)

在多个应用间共享用户身份

4. API 认证

为 RESTful API 提供无状态认证

5. 移动应用

适合移动应用的认证需求

JWT 的安全考虑

1. 密钥管理
  • 使用强密钥
  • 定期轮换密钥
  • 安全存储密钥
2. 传输安全
  • 始终使用 HTTPS
  • 避免在 URL 中传递 JWT
3. 存储安全
  • 避免存储在 localStorage(XSS 风险)
  • 考虑使用 httpOnly cookie
  • 实现 CSRF 保护
4. 令牌过期
  • 设置合理的过期时间
  • 实现刷新令牌机制
5. 算法选择
  • 使用强加密算法(如 RS256)
  • 避免使用 none 算法

实际代码示例

Node.js 示例
安装依赖
npm install jsonwebtoken 
生成 JWT
const jwt = require('jsonwebtoken');
// 密钥(生产环境中应使用环境变量)
const secretKey = 'your-secret-key';
// 用户信息
const user = { id: 1, username: 'john_doe', role: 'admin' };
// 生成 JWT
const token = jwt.sign({ sub: user.id, username: user.username, role: user.role }, secretKey, {
  expiresIn: '1h', // 1 小时过期
  issuer: 'your-app',
  audience: 'your-users'
});
console.log('Generated JWT:', token);
验证 JWT
const jwt = require('jsonwebtoken');
// 验证 JWT 中间件
const authenticateToken = (req, res, next) => {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
  if (!token) {
    return res.status(401).json({ error: 'Access token required' });
  }
  jwt.verify(token, secretKey, (err, decoded) => {
    if (err) {
      return res.status(403).json({ error: 'Invalid token' });
    }
    req.user = decoded;
    next();
  });
};
// 使用示例
app.get('/protected', authenticateToken, (req, res) => {
  res.json({ message: 'This is a protected route', user: req.user });
});
刷新令牌实现
const refreshTokens = new Set(); // 生产环境中应使用数据库
// 生成访问令牌和刷新令牌
const generateTokens = (user) => {
  const accessToken = jwt.sign({ sub: user.id, username: user.username }, secretKey, {
    expiresIn: '15m'
  });
  const refreshToken = jwt.sign({ sub: user.id, type: 'refresh' }, secretKey, {
    expiresIn: '7d'
  });
  refreshTokens.add(refreshToken);
  return { accessToken, refreshToken };
};
// 刷新令牌端点
app.post('/refresh', (req, res) => {
  const { refreshToken } = req.body;
  if (!refreshToken || !refreshTokens.has(refreshToken)) {
    return res.status(403).json({ error: 'Invalid refresh token' });
  }
  try {
    const decoded = jwt.verify(refreshToken, secretKey);
    if (decoded.type !== 'refresh') {
      return res.status(403).json({ error: 'Invalid token type' });
    }
    // 生成新的访问令牌
    const newAccessToken = jwt.sign({ sub: decoded.sub }, secretKey, {
      expiresIn: '15m'
    });
    res.json({ accessToken: newAccessToken });
  } catch (error) {
    res.status(403).json({ error: 'Invalid refresh token' });
  }
});
Python 示例
安装依赖
pip install PyJWT 
生成和验证 JWT
import jwt
import datetime
from functools import wraps

# 密钥
SECRET_KEY = 'your-secret-key'

def generate_token(user_id, username, role):
    """生成 JWT 令牌"""
    payload = {
        'sub': user_id,
        'username': username,
        'role': role,
        'iat': datetime.datetime.utcnow(),
        'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1)
    }
    token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
    return token

def verify_token(token):
    """验证 JWT 令牌"""
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
        return payload
    except jwt.ExpiredSignatureError:
        raise Exception('Token has expired')
    except jwt.InvalidTokenError:
        raise Exception('Invalid token')

def token_required(f):
    """装饰器:需要 JWT 令牌"""
    @wraps(f)
    def decorated(*args, **kwargs):
        token = None
        if 'Authorization' in request.headers:
            auth_header = request.headers['Authorization']
            try:
                token = auth_header.split(" ")[1] # Bearer TOKEN
            except IndexError:
                return {'message': 'Token format invalid'}, 401
        if not token:
            return {'message': 'Token is missing'}, 401
        try:
            data = verify_token(token)
            current_user = data
        except Exception as e:
            return {'message': str(e)}, 401
        return f(current_user, *args, **kwargs)
    return decorated

# 使用示例
@app.route('/protected')
@token_required
def protected(current_user):
    return {'message': 'This is a protected route', 'user': current_user}
前端 JavaScript 示例
存储和发送 JWT
// 存储 JWT
localStorage.setItem('accessToken', token);

// 发送请求时携带 JWT
const apiCall = async (url, options = {}) => {
  const token = localStorage.getItem('accessToken');
  const config = {
    ...options,
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`,
      ...options.headers
    }
  };
  try {
    const response = await fetch(url, config);
    if (response.status === 401) {
      // 令牌过期,尝试刷新
      await refreshToken();
      // 重新发送请求
      return fetch(url, config);
    }
    return response;
  } catch (error) {
    console.error('API call failed:', error);
    throw error;
  }
};

// 刷新令牌
const refreshToken = async () => {
  const refreshToken = localStorage.getItem('refreshToken');
  try {
    const response = await fetch('/api/refresh', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ refreshToken })
    });
    if (response.ok) {
      const { accessToken } = await response.json();
      localStorage.setItem('accessToken', accessToken);
    } else {
      // 刷新失败,重定向到登录页
      window.location.href = '/login';
    }
  } catch (error) {
    console.error('Token refresh failed:', error);
    window.location.href = '/login';
  }
};

最佳实践

1. 安全最佳实践
  • 使用强密钥(至少 256 位)
  • 设置合理的过期时间
  • 使用 HTTPS 传输
  • 实现令牌刷新机制
  • 避免在 URL 中传递敏感令牌
2. 性能优化
  • 缓存公钥(使用 RS256 时)
  • 使用适当的过期时间
  • 考虑令牌大小对性能的影响
3. 错误处理
  • 提供清晰的错误信息
  • 实现优雅的令牌过期处理
  • 记录安全相关事件
4. 监控和日志
  • 监控令牌使用情况
  • 记录异常访问模式
  • 实现安全审计

常见问题与解决方案

1. 令牌过期处理

问题:用户在使用过程中令牌过期 解决方案:

  • 实现自动刷新机制
  • 提供友好的重新登录提示
  • 使用较长的刷新令牌
2. 跨域问题

问题:CORS 策略阻止 JWT 传输 解决方案:

  • 配置正确的 CORS 策略
  • 使用 withCredentials 选项
  • 考虑使用 cookie 存储
3. 令牌撤销

问题:无法主动撤销 JWT 解决方案:

  • 维护令牌黑名单
  • 使用短期令牌
  • 实现服务器端会话管理
4. 安全存储

问题:客户端存储 JWT 的安全风险 解决方案:

  • 使用 httpOnly cookie
  • 实现 CSRF 保护
  • 考虑使用内存存储
5. 性能问题

问题:大量请求导致验证性能问题 解决方案:

  • 使用 RS256 算法(公钥验证)
  • 实现令牌缓存
  • 优化验证逻辑

总结

JWT 是一种强大的身份验证和信息交换标准,特别适合现代 Web 应用和微服务架构。通过理解 JWT 的结构、工作原理和安全考虑,可以有效地在项目中使用 JWT。

关键要点:

  • JWT 是自包含的、无状态的令牌
  • 由 Header、Payload 和 Signature 三部分组成
  • 适合分布式系统和 API 认证
  • 需要仔细考虑安全性和性能
  • 实现时要注意最佳实践

选择合适的认证方案需要根据具体需求和安全要求来决定。JWT 不是万能的,但在合适的场景下,它是一个优秀的选择。

目录

  1. JWT(JSON Web Token)详解
  2. 什么是 JWT
  3. 核心特点
  4. JWT 的结构
  5. 1. Header(头部)
  6. 2. Payload(载荷)
  7. 标准声明(Registered Claims)
  8. 公共声明(Public Claims)
  9. 私有声明(Private Claims)
  10. 3. Signature(签名)
  11. JWT 的工作原理
  12. 认证流程
  13. 流程图
  14. JWT 的优势与劣势
  15. 优势
  16. 劣势
  17. JWT 的使用场景
  18. 1. 身份验证
  19. 2. 信息交换
  20. 3. 单点登录(SSO)
  21. 4. API 认证
  22. 5. 移动应用
  23. JWT 的安全考虑
  24. 1. 密钥管理
  25. 2. 传输安全
  26. 3. 存储安全
  27. 4. 令牌过期
  28. 5. 算法选择
  29. 实际代码示例
  30. Node.js 示例
  31. 安装依赖
  32. 生成 JWT
  33. 验证 JWT
  34. 刷新令牌实现
  35. Python 示例
  36. 安装依赖
  37. 生成和验证 JWT
  38. 密钥
  39. 使用示例
  40. 前端 JavaScript 示例
  41. 存储和发送 JWT
  42. 最佳实践
  43. 1. 安全最佳实践
  44. 2. 性能优化
  45. 3. 错误处理
  46. 4. 监控和日志
  47. 常见问题与解决方案
  48. 1. 令牌过期处理
  49. 2. 跨域问题
  50. 3. 令牌撤销
  51. 4. 安全存储
  52. 5. 性能问题
  53. 总结

更多推荐文章

查看全部
  • LangChain 输出解析器与 LCEL 链构建详解
  • Java 常用 API 与日期工具详解及异常处理
  • 无人机飞行空域申请与合规操作指南
  • 张一鸣:10 年面试 2000 人,发现优秀者的共同特质
  • ChatGPT 如何利用结构化原则实现高效信息管理
  • Agent-Reach:零成本实现 AI 跨平台互联网访问
  • 半小时基于 OpenClaw 搭建 AI 量化系统:开源三件套实测
  • 2025 无人机四大顶会精选:16 篇前沿论文解析(IROS/ICRA/RSS/CoRL)
  • Python 实现斗地主纸牌游戏
  • LLaMA-Factory 大模型微调与部署实战
  • Linux Shell join 命令实战指南
  • OrangePlayer:功能完整的 Android 视频播放器开源库
  • 人工智能、机器学习与深度学习的本质区别
  • Windows 系统安装与配置 Neo4j 图数据库指南
  • 基于 LangChain 构建具备记忆功能的聊天机器人
  • AI 内容创作:利用身份对立打造抖音爆款图文策略
  • 华为 OD 机试双机位 C 卷 - 叠积木
  • 大模型应用开发实战指南:基于 GPT-4 和 ChatGPT 的核心技术与实践
  • Linux 文件系统详解:从硬件结构到 inode 机制
  • PyCharm 安装详细教程及配置指南

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online