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

Python解码JWT遇Invalid Header Padding及Base64密钥解码问题

问题根源分析
  1. Java JJWT库的密钥处理逻辑:Java代码里的signWith(SignatureAlgorithm.HS512, jwtSecret)方法,当传入字符串类型密钥时,会自动把该字符串当作Base64编码的密钥,对其执行Base64解码得到原始字节数组,再用于HMAC签名。
  2. Python PyJWT库的密钥处理差异:PyJWT默认会将字符串密钥直接转为UTF-8字节用于验证;要匹配Java的逻辑,必须手动对SECRET_KEY做Base64解码得到字节数组,且不能把解码后的字节转成UTF-8字符串(这就是你触发UnicodeDecodeError的原因——Base64解码后的原始密钥字节未必是合法的UTF-8编码)。
  3. 额外细节问题:初始代码未正确提取Authorization头里的token(需去掉Bearer 前缀),调整后的代码处理了这一点,但密钥逻辑依旧错误。
解决方案
  • 严格校验并提取Authorization头中的JWT令牌(确保去掉Bearer 前缀)。
  • 将Python中与Java配置文件jwt.secret一致的SECRET_KEY字符串,执行Base64解码得到字节数组,直接作为PyJWT的解码密钥,跳过UTF-8转换步骤。
  • 确保解码时指定的算法与Java生成时完全一致(HS512)。
修正后的Python解码代码
import base64
from flask import request, jsonify
import jwt
from jwt.exceptions import InvalidTokenError
from config import SECRET_KEY


def authenticate_token(func, require_premium=False):
    """
    :param require_premium: True if the endpoint is only for premium users
    :param func: the function that is being wrapped around
    :return: returns the wrapped function itself
    """
    def wrapper(*args, **kwargs):
        auth_header = request.headers.get('Authorization')
        if not auth_header or not auth_header.startswith('Bearer '):
            return jsonify(message='Authorization token is missing or invalid'), 401
        
        token = auth_header.split()[1]
        try:
            # 对SECRET_KEY做Base64解码得到字节数组,直接作为校验密钥
            decoded_secret = base64.b64decode(SECRET_KEY)
            decoded = jwt.decode(
                token, 
                decoded_secret, 
                algorithms=['HS512'],
                # 可选:开启过期时间验证,匹配Java令牌的有效期逻辑
                options={"verify_exp": True}
            )
            
            # 此处添加premium用户校验逻辑
            if require_premium:
                # 示例:检查解码后的令牌是否包含 premium 标识
                # if not decoded.get('premium', False):
                #     return jsonify(message='Premium access required'), 403
                pass
                
        except InvalidTokenError as e:
            return jsonify(message=f'Invalid token: {e}'), 401
        except base64.binascii.Error as e:
            return jsonify(message=f'Invalid secret key encoding: {e}'), 500

        return func(*args, **kwargs)

    return wrapper
关键改动说明
  • 增强了Authorization头的校验逻辑,避免非法格式的请求头。
  • 直接使用Base64解码后的字节数组作为密钥,解决了Unicode解码错误问题。
  • 添加了Base64解码错误的捕获,便于排查密钥本身的编码问题。
  • 可选开启过期时间验证,与Java生成的令牌逻辑保持一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 23:45:27