You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python 3.7中修改JWT头部顺序?PyJWT头部顺序不符问题求解

这个问题我之前也碰到过!PyJWT默认会对JWT头部的键按字母顺序排序,所以生成的是typ在前、alg在后的结构,但目标JWT的字段顺序反过来,导致签名验证失败——毕竟JWT的签名是基于头部和Payload的Base64编码拼接后的内容,字段顺序不同的话,Base64结果完全不一样,签名自然对不上。

下面给你两种可行的解决方案:

方案一:利用PyJWT自带参数控制头部顺序

如果你用的是PyJWT 2.0+版本(建议升级到最新版),可以通过json_kwargs参数关闭键排序,同时自定义头部的字段顺序:

import jwt
import json

payload = {'some': 'payload'}
secret = 'secret'

# 按我们需要的顺序定义头部字典(Python3.7+字典默认保留插入顺序)
custom_headers = {'alg': 'HS512', 'typ': 'JWT'}

# 生成符合要求的JWT
token = jwt.encode(
    payload,
    secret,
    algorithm='HS512',
    headers=custom_headers,
    json_kwargs={'sort_keys': False}
)

print(token)
# 生成的token解码后头部会是 {"alg":"HS512","typ":"JWT"}

这里的json_kwargs={'sort_keys': False}会传递给底层的json.dumps方法,告诉序列化器不要对字典键进行排序,从而严格保留我们定义的头部字段顺序。

方案二:手动构造JWT(完全可控)

如果你的PyJWT版本较旧,或者需要更精细的控制,可以完全手动实现JWT的生成流程,彻底绕过PyJWT的默认逻辑:

import base64
import hashlib
import hmac
import json

def generate_jwt_with_custom_header_order(payload, secret, algorithm='HS512'):
    # 1. 构造并序列化头部,严格控制字段顺序
    header = {'alg': algorithm, 'typ': 'JWT'}
    # 使用separators去掉空格,符合JWT的紧凑格式要求
    header_json = json.dumps(header, separators=(',', ':'), sort_keys=False).encode('utf-8')
    # URL安全Base64编码,移除末尾的=符号
    header_b64 = base64.urlsafe_b64encode(header_json).rstrip(b'=').decode('utf-8')

    # 2. 序列化Payload(如果需要也可以控制顺序,一般Payload顺序不影响签名验证)
    payload_json = json.dumps(payload, separators=(',', ':'), sort_keys=False).encode('utf-8')
    payload_b64 = base64.urlsafe_b64encode(payload_json).rstrip(b'=').decode('utf-8')

    # 3. 计算HS512签名
    signing_input = f"{header_b64}.{payload_b64}".encode('utf-8')
    if algorithm == 'HS512':
        signature = hmac.new(secret.encode('utf-8'), signing_input, hashlib.sha512).digest()
    else:
        raise ValueError(f"暂不支持该算法:{algorithm}")
    signature_b64 = base64.urlsafe_b64encode(signature).rstrip(b'=').decode('utf-8')

    # 4. 拼接成最终JWT
    return f"{header_b64}.{payload_b64}.{signature_b64}"

# 使用示例
token = generate_jwt_with_custom_header_order({'some': 'payload'}, 'secret', 'HS512')
print(token)

这种方法完全由你掌控每一步的处理逻辑,头部顺序绝对不会出现偏差,适合需要高度定制的场景。

内容的提问来源于stack exchange,提问作者user10243206

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:53:43