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

PHP转Python实现Bearer Token生成遇401错误,求排查

问题:PHP生成的Bearer Token可用,Python复现返回401

我有一段PHP脚本,可通过用户ID和密码生成有效的Bearer Token,但用Python复现相同逻辑时,始终返回401错误。PHP脚本会将生成的JWT按.拆分后,取第2、3个元素(索引1和2)拼接输出,Python中我执行了同样的拼接操作,但问题依旧。

PHP 实现代码

#!/usr/bin/env php
<?php
require __DIR__ . '/app/vendor/php-jwt/JWT.php';

/*
 * Acquisition date are UTC dates
 */
date_default_timezone_set('UTC');
/*
 * Default values
 */
$days = 1;
$help = "\nGenerate a resto JSON Web Token (aka rJWT) authentication token for user\n";
$help  .= "\n   USAGE : generateAuthToken [options] \n";
$help .= "   OPTIONS:\n";
$help .= "          -i [bigint] : userid (mandatory)\n";
$help .= "          -d [int] : duration of token in days (default " . $days . ")\n\n";
$help .= "          -p [string] : passphrase (mandatory)\n";

$options = getopt("d:i:p:h");
/*
 * Default values
 */
$days = 1;
$options = getopt("i:d:p:h");
foreach ($options as $option => $value) {
    if ($option === "d") {
        $days = $value;
    }
    if ($option === "i") {
        $userid = $value;
    }
    if ($option === "p") {
        $passphrase = $value;
    }
}

$exp = time() + (86400 * $days);
$splitJWT = explode('.', JWT::encode(array(
    'sub' => $userid,
    'iat' => time(),
    'exp' => time() + (86400 * $days)
), $passphrase));

echo "$splitJWT[1].$splitJWT[2]";
?>

Python 原实现代码

from datetime import datetime, timedelta
import jwt

JWT_SECRET = '<>'
JWT_ALGORITHM = 'HS256'
JWT_EXP_DELTA_SECONDS = 86400
ADMIN_USER_ID="<>""

payload = {
    'user_id': ADMIN_USER_ID,
    'exp': datetime.utcnow() + timedelta(seconds=JWT_EXP_DELTA_SECONDS)
}

print(payload)

encoded_jwt = jwt.encode(payload, JWT_SECRET , algorithm='HS256')
x = encoded_jwt.split(".")
x1 =  x[1] + "." + x[2]
print(x1)

问题根源及修正方案

核心差异点

  1. Payload字段不匹配:PHP中用sub存储用户ID,而Python用user_id,服务端验证时会无法识别用户身份,这是401的主要原因。
  2. 缺少iat字段:PHP的Payload包含iat(签发时间戳),部分服务端会校验该字段的存在性。
  3. 时间格式差异:PHP用整数时间戳,Python用datetime对象,虽然pyjwt能自动转换,但统一用时间戳更稳妥。

修正后的Python代码

import time
import jwt

JWT_SECRET = '<>'
JWT_ALGORITHM = 'HS256'
JWT_EXP_DELTA_SECONDS = 86400
ADMIN_USER_ID = "<>"

current_timestamp = int(time.time())
payload = {
    'sub': ADMIN_USER_ID,  # 改为和PHP一致的sub字段
    'iat': current_timestamp,  # 新增签发时间字段
    'exp': current_timestamp + JWT_EXP_DELTA_SECONDS  # 用整数时间戳
}

encoded_jwt = jwt.encode(payload, JWT_SECRET, algorithm=JWT_ALGORITHM)
x = encoded_jwt.split(".")
x1 = x[1] + "." + x[2]
print(x1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 09:05:20