Administrator
Published on 2025-03-12 / 9 Visits
0
0

JWT Token 原理与应用详解

图标
文章摘要
LIK.CC-GPT

JSON Web Token(JWT)是一种开放标准(RFC 7519),用于在各方之间安全传输信息。它通过紧凑且自包含的方式(通常以JSON对象形式)传递声明(Claims),适用于身份验证、授权和信息交换等场景。 核心结构 JWT由三部分组成,用点(.)分隔: Header(头部) 包含令牌类型

JSON Web Token(JWT)是一种开放标准(RFC 7519),用于在各方之间安全传输信息。它通过紧凑且自包含的方式(通常以JSON对象形式)传递声明(Claims),适用于身份验证、授权和信息交换等场景。


核心结构

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

  1. Header(头部)

    • 包含令牌类型(typ: "JWT")和签名算法(如alg: HS256RS256)。
    • 示例:{"alg": "HS256", "typ": "JWT"}
    • 使用Base64Url编码。
  2. Payload(载荷)

    • 存放实际数据(声明),分为三类:
      • Registered Claims(预定义声明):如iss(签发者)、exp(过期时间)、sub(主题)等。
      • Public Claims(公开声明):自定义但需避免冲突的声明。
      • Private Claims(私有声明):应用自定义的数据,如用户ID。
    • 示例:{"sub": "user123", "exp": 1620000000}
    • 使用Base64Url编码。
  3. Signature(签名)

    • 将编码后的Header和Payload与密钥(Secret)通过指定算法(如HMAC SHA256)签名,确保数据完整性和真实性。
    • 公式:HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

完整JWT示例:
Header.Payload.Signaturexxxxx.yyyyy.zzzzz


工作流程

  1. 用户登录:客户端发送凭证(如用户名密码)到服务器。
  2. 生成JWT:服务器验证凭证,生成JWT并返回。
  3. 客户端存储:客户端将JWT保存(如LocalStorage或Cookie)。
  4. 携带Token请求:后续请求在Authorization头中携带JWT(如Bearer <token>)。
  5. 服务器验证:服务器验证签名和声明(如是否过期)后处理请求。

优点

  1. 无状态:服务端无需存储会话信息,适合分布式系统。
  2. 跨域支持:适用于前后端分离、跨域API调用。
  3. 自包含性:Payload可直接包含用户信息,减少数据库查询。
  4. 灵活性:支持多种签名算法(对称HMAC或非对称RSA/ECDSA)。

缺点

  1. 无法撤销:签发后需等待过期,需结合黑名单或短期Token解决。
  2. 存储风险:客户端存储不当可能导致XSS攻击窃取Token。
  3. 数据暴露:Payload仅Base64编码(非加密),敏感信息需加密处理。
  4. 体积较大:相比Session ID,JWT可能增加请求头大小。

安全实践

  1. 使用HTTPS:防止Token在传输中被截获。
  2. 设置合理过期时间:缩短有效期,结合Refresh Token续签。
  3. 避免敏感数据:Payload中不存密码等机密信息。
  4. 签名算法选择:优先使用非对称算法(如RS256)增强安全性。
  5. 防范XSS:避免LocalStorage存储,使用HttpOnly Cookie。

应用场景

  • 身份验证:用户登录后获取JWT,后续请求验证。
  • 单点登录(SSO):一次登录多系统共享Token。
  • API认证:微服务间通过JWT传递用户身份。
  • 移动端认证:减少对Cookie的依赖。

示例代码(Python)

使用 PyJWT 库实现 JWT 的生成与验证:

1. 安装依赖

pip install pyjwt

2. 生成和验证 Token

import jwt
import datetime

# 生成 Token
def generate_jwt():
    payload = {
        "user_id": 123,
        "role": "admin",
        # 设置过期时间(1小时后)
        "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1)
    }
    secret = "your-secret-key"
    token = jwt.encode(payload, secret, algorithm="HS256")
    return token

# 验证 Token
def verify_jwt(token):
    secret = "your-secret-key"
    try:
        decoded = jwt.decode(token, secret, algorithms=["HS256"])
        return decoded
    except jwt.ExpiredSignatureError:
        print("Token 已过期")
    except jwt.InvalidTokenError:
        print("无效 Token")

# 测试
if __name__ == "__main__":
    token = generate_jwt()
    print("生成的 Token:", token)
    
    decoded_data = verify_jwt(token)
    if decoded_data:
        print("解码后的数据:", decoded_data)

总结

JWT适用于需要无状态、跨域或分布式的场景,但需注意安全性和存储方式。在设计时需权衡便利性与风险,结合业务需求选择合适的验证机制。


Comment