You need to enable JavaScript to run this app. ES256算法凭证使用:Python调用Bearer认证API的令牌生成问题
优惠活动
大模型
产品
解决方案
定价
更多

ES256算法凭证使用:Python调用Bearer认证API的令牌生成问题

凭证与Bearer Token的对应逻辑

你持有的这套带非对称密钥对的凭证,不是可以直接当Bearer token用的静态字符串,而是用来生成合法访问凭证的本地配置材料,这也是之前直接拿公钥、私钥、整个凭证字典当token失败的核心原因。
各字段的实际作用:

  • id:客户端唯一身份标识,对应JWT声明里的签发者iss
  • algorithm:指定JWT签名所用的加密算法(常见为RS256、ES256等非对称算法)
  • private_key:本地用来给JWT做签名的密钥,除生成签名的场景外绝对不能外传
  • public_key:API服务端留存的验签材料,本地生成请求时完全不会用到
  • key_id:对应JWT头部的kid字段,告知服务端使用哪套公开公钥完成验签
  • secret:对称加密场景下的备用签名密钥,仅当指定算法为HS256这类对称算法时才会用到
合法Bearer Token的生成规则

根据API的实现逻辑,分两类常见场景对应不同的token结构:

场景1:无状态自签名模式(本地生成的JWT直接作为Bearer token)

这类API不需要额外请求token端点,你本地生成的标准三段式JWT,就是合法的Bearer token,结构为header.payload.signature,每段均为Base64URL编码格式:

  • JWT头部内容需包含:
    • alg: 匹配凭证里的algorithm值
    • kid: 匹配凭证里的key_id值
    • typ: 固定为JWT
  • JWT负载内容需包含API要求的强制声明:
    • iss: 匹配凭证里的id值
    • iat: 当前Unix时间戳(签发时间)
    • exp: 签发时间1~5分钟后的Unix时间戳(过期时间,通常API要求有效期不超过5分钟)
    • 部分API要求附加aud字段,值为目标API的基础访问地址
  • 签名部分:用凭证里的private_key,按照指定算法对前两部分的编码内容做签名,再将签名结果做Base64URL编码拼接为第三段。

场景2:标准OAuth2客户端凭证模式(需换正式access token)

这类API遵循标准OAuth2流程,你本地生成的自签名JWT仅作为请求凭证,需要先向API提供方指定的token端点发起POST请求,换取的access_token才是实际放在Bearer请求头里的合法token:

  • 请求头要求:Content-Type: application/x-www-form-urlencoded
  • 请求体固定参数:
    • grant_type: 固定值client_credentials
    • client_assertion_type: 固定值urn:ietf:params:oauth:client-assertion-type:jwt-bearer
    • client_assertion: 本地生成的自签名JWT字符串
  • 接口返回JSON中的access_token字段,即为业务接口调用所需的合法凭证。
Python端实现参考代码
import time
import jwt
from cryptography.hazmat.primitives import serialization

# 已解密完成的凭证字典
cred = {
    "id": "对应你的客户端ID值",
    "secret": "预留对称加密密钥,非对称算法场景下不使用",
    "public_key": "服务端验签用公钥,本地调用时不使用",
    "algorithm": "RS256",
    "private_key": "PEM格式的私钥字符串",
    "key_id": "对应凭证里的key_id值"
}

# 加载PEM格式私钥
private_key = serialization.load_pem_private_key(
    data=cred["private_key"].encode(),
    password=None
)

# 构造JWT负载
jwt_payload = {
    "iss": cred["id"],
    "iat": int(time.time()),
    "exp": int(time.time()) + 300,  # 5分钟有效期
    "aud": "目标API的基础访问地址"
}

# 生成带kid头部的自签名JWT
signed_jwt = jwt.encode(
    payload=jwt_payload,
    key=private_key,
    algorithm=cred["algorithm"],
    headers={"kid": cred["key_id"]}
)

常见排查项:如果生成的token仍校验不通过,优先检查三个问题:

  • JWT的过期时间是否超出API允许的最大有效期限制
  • 私钥格式是否存在换行缺失、编码错误等问题
  • 签名算法是否和API要求的算法完全匹配,不存在算法混淆

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.05 10:15:03