JWT的生成和工作原理

发布于:2025-02-11 ⋅ 阅读:(56) ⋅ 点赞:(0)

深入了解 JWT(JSON Web Token)

在现代 Web 应用和分布式系统中,身份验证和授权是两个关键的部分。为了应对这些需求,JWT(JSON Web Token) 应运而生。它作为一种紧凑的、安全的、URL 安全的令牌格式,广泛应用于身份验证和信息交换中。本文将深入探讨 JWT 的结构、工作原理、优缺点以及常见的应用场景,帮助你更好地理解并运用 JWT。

什么是 JWT?

JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在各方之间以 JSON 对象的形式安全地传递信息。JWT 主要由三部分组成:

  1. 头部(Header)
  2. 载荷(Payload)
  3. 签名(Signature)

这些部分通过 Base64 URL 编码 后组合在一起,形成一个完整的 JWT Token,通常用于 身份验证信息交换

JWT 的结构

JWT 的结构是由三部分组成,并通过点(.)连接在一起:

<Header>.<Payload>.<Signature>

1. Header(头部)

头部通常包含两部分信息:

  • alg(算法):指定签名使用的算法,比如 HMAC SHA256(HS256)或 RSA(RS256)。
  • typ(类型):通常是 JWT,表示这是一个 JSON Web Token。

示例:

{
  "alg": "HS256",
  "typ": "JWT"
}

编码后的 Header 部分会是:

eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9

2. Payload(载荷)

Payload 部分包含 JWT 的 声明(Claims)。声明是关于实体(通常是用户)及其他数据的声明。JWT 有三种类型的声明:

  • 注册声明(Registered Claims):这些是 JWT 预定义的标准声明,如 sub(主题)、iat(签发时间)、exp(过期时间)、aud(受众)等。
  • 公共声明(Public Claims):可以自定义,避免与其他人冲突。
  • 私有声明(Private Claims):由使用者自定义,适用于在两方之间传递信息。

示例:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

编码后的 Payload 部分会是:

eyJzdWIiOiAiMTIzNDU2Nzg5MCIsICJuYW1lIjogIkpvaG4gRG9lIiwgImlhdCI6IDE1MTYyMzkwMjJ9

3. Signature(签名)

签名用于确保消息的完整性,并验证发送者的身份。为了生成签名,你需要知道密钥,并选择一种签名算法(如 HMAC SHA256)。签名的生成过程如下:

  • HeaderPayload 使用 Base64 URL 编码。
  • 使用密钥和签名算法(如 HS256)对 HeaderPayload 拼接的结果进行签名。

签名的计算公式

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

示例签名

f1f99fa2445973487d469b1b3e4b38c53a8c9c8fa55e3e08e52a970e9cfbce18

最终生成的完整 JWT 会是:

eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiAiMTIzNDU2Nzg5MCIsICJuYW1lIjogIkpvaG4gRG9lIiwgImlhdCI6IDE1MTYyMzkwMjJ9.f1f99fa2445973487d469b1b3e4b38c53a8c9c8fa55e3e08e52a970e9cfbce18

 例子:

   1. jwt生成


import jwt
import time

# 定义头部信息
header = {
    "alg": "HS256",
    "typ": "JWT"
}

# 定义载荷信息(与提供的相同的时间戳等信息)
payload = {
    "username": "www.json.cn",
    "sub": "demo",
    "iat": 1735033926,  # 签发时间
    "nbf": 1735033926,  # 生效时间
    "exp": 1735120326  # 过期时间
}

# 对称密钥
secret_key = "json.cn"

# 生成JWT Token
encoded_jwt = jwt.encode(payload, secret_key, algorithm="HS256", headers=header)

# 输出生成的JWT Token
print("Generated JWT Token:", encoded_jwt)

# 如果需要验证JWT Token是否有效
decoded_jwt = jwt.decode(encoded_jwt, secret_key, algorithms=["HS256"])
print("Decoded JWT:", decoded_jwt)

2. 手动生成 


import base64
import json
import hashlib
import hmac

# 头部信息
header = {
    "alg": "HS256",
    "typ": "JWT"
}

# 载荷信息
payload = {
    "username": "www.json.cn",
    "sub": "demo",
    "iat": 1735035050,
    "nbf": 1735035050,
    "exp": 1735121450
}

# 密钥
secret_key = "json.cn"


# 生成 JWT
def encode_jwt(header, payload, secret_key):
    # Base64 URL 编码函数
    def base64_url_encode(data):
        return base64.urlsafe_b64encode(data).rstrip(b'=')

    # 将头部和载荷转换为 JSON 字符串
    header_json = json.dumps(header, separators=(',', ':')).encode('utf-8')
    payload_json = json.dumps(payload, separators=(',', ':')).encode('utf-8')

    # Base64 URL 编码头部和载荷
    header_b64 = base64_url_encode(header_json)
    payload_b64 = base64_url_encode(payload_json)

    # 创建签名
    message = header_b64 + b"." + payload_b64
    signature = hmac.new(secret_key.encode('utf-8'), message, hashlib.sha256).digest()

    # Base64 URL 编码签名
    signature_b64 = base64_url_encode(signature)

    # 拼接最终的 JWT
    jwt_token = header_b64 + b"." + payload_b64 + b"." + signature_b64
    return jwt_token.decode('utf-8')


# 生成 JWT Token
jwt_token = encode_jwt(header, payload, secret_key)

print(jwt_token)


jwt源码实现:

1. 进到编码方法

 

2. 序列化payload 

 3. 执行父类方法 序列法header

4.  等于号别替换成了空

 

5. 返回签名

JWT 工作原理

JWT 的工作原理主要分为三个阶段:生成传输验证

1. JWT 生成

  • 用户登录时,服务器验证用户的凭证(如用户名和密码)。如果凭证有效,服务器会生成一个 JWT。
  • 服务器将用户的信息(如用户 ID、角色等)作为载荷放入 JWT 中。然后,使用密钥对 JWT 进行签名,确保其安全性和完整性。
  • 生成的 JWT 会发送给用户,通常通过 HTTP 头部传递。

2. JWT 传输

生成的 JWT 会在后续的请求中传递给服务器。最常见的传输方式是将 JWT 放在 Authorization Header 中,使用 Bearer 方案:

Authorization: Bearer <JWT>

JWT 也可以存储在 Cookies 中。

3. JWT 验证

当客户端发起请求时,JWT 会被包含在请求头或 Cookies 中,服务器接收到 JWT 后进行以下验证:

  1. 解码:服务器解析 JWT,并分离出 HeaderPayloadSignature
  2. 验证签名:服务器使用密钥验证签名,确保数据未被篡改。
  3. 验证过期时间:如果 JWT 包含 exp(过期时间)声明,服务器会检查当前时间是否在有效期内。

JWT 的优缺点

优点
  1. 无状态:JWT 是自包含的,它不依赖于服务器端的会话存储,因此服务器不需要维护用户的会话状态,减轻了服务器负担。
  2. 跨平台支持:JWT 是 JSON 格式,易于解析,且能在不同的编程语言之间传递。
  3. 适用于分布式系统:因为它不依赖服务器存储,JWT 非常适合微服务架构等分布式系统。
  4. 灵活性高:JWT 可以存储多种类型的声明,可以扩展和定制。
缺点
  1. 不可撤销性:一旦 JWT 被签发,它就无法撤销,除非在服务器端维护一个黑名单,这对长时间使用的令牌可能会造成一定问题。
  2. 安全性:如果签名密钥泄露,攻击者可以伪造 JWT。为了保障安全性,必须使用强大的密钥,并且定期更新。
  3. Token 大小:虽然 JWT 是自包含的,但它的大小比传统的 Session ID 大,尤其是在存储大量信息时,可能会影响请求的效率。

JWT 的常见应用场景

JWT 主要用于以下几个场景:

1. 身份验证(Authentication)

最常见的应用场景是身份验证。用户登录后,服务器生成 JWT 令牌,并将其返回给客户端。客户端在之后的请求中使用该 JWT 令牌进行身份验证,而不需要每次都发送用户名和密码。

2. 授权(Authorization)

JWT 还可以用来进行授权。在请求中,JWT 会携带用户的身份信息和权限,服务器可以根据这些信息判断用户是否有权限访问特定资源。

3. 信息交换(Information Exchange)

JWT 也常用于在不同系统间交换信息,特别是当需要保证数据的完整性和不可篡改时。由于 JWT 可以被签名,它提供了一个可靠的机制来验证数据来源的真实性。

总结

JWT 是一种非常流行且强大的身份验证与信息交换标准。它具有自包含、无状态等特点,适合分布式系统和微服务架构的应用。然而,在使用 JWT 时,必须注意密钥的安全性、令牌的过期时间以及不可撤销性等问题。了解 JWT 的结构和工作原理,将帮助你在实际开发中更好地运用它,提升应用的安全性与可扩展性。