使用ES256 JWT调用Coinbase Advanced API始终返回401无效令牌的问题排查求助
ES256 JWT调用Coinbase Advanced API始终返回401无效令牌的问题排查求助
我最近在尝试用ES256签名的JWT认证Coinbase Advanced API,但所有请求都返回401 Unauthorized,响应体固定是:
{"error":"invalid_token"}
我已经逐一核对了官方文档里的要求,但还是没找到问题所在,想请教各位有没有遇到过类似情况,或者我是不是遗漏了某些未明确说明的细节?
已确认的配置项
- 我在Coinbase开发者平台(CDP)创建的JSON API密钥已经配置了对应接口的权限
- JWT头部的
kid字段和API密钥的id完全一致 sub声明严格匹配密钥的name字段(格式为organizations/xxx/apiKeys/xxx)- 令牌确实使用ES256算法签名
aud字段设置为https://api.coinbase.comnbf设为当前时间,exp设为当前时间+120秒,时间窗口完全在有效范围内- 每个请求都会重新生成新的JWT,没有复用过期令牌
- HTTP请求的
Authorization头部正确格式为Bearer <生成的JWT令牌>
简化后的JWT生成代码
import jwt import json import time from pathlib import Path from cryptography.hazmat.primitives import serialization # 加载Coinbase CDP的JSON API密钥 with open("cdp_api_key.json", "r") as f: key_data = json.load(f) # 加载EC私钥文件 with open("private_key.pem", "r") as f: private_key = serialization.load_pem_private_key( f.read().encode(), password=None, ) now = int(time.time()) # JWT载荷配置 payload = { "sub": key_data["name"], "iss": key_data["name"], "nbf": now, "exp": now + 120, "aud": "https://api.coinbase.com", } # 生成ES256签名的JWT token = jwt.encode( payload, private_key, algorithm="ES256", headers={"kid": key_data["id"]}, ) print(token)
几个疑问点
- 是不是
sub和iss字段的取值有特殊要求?我现在把两者都设为密钥的name,是否符合Coinbase的校验逻辑? - 加载PEM私钥的方式有没有潜在问题?比如序列化的过程是否需要额外配置?
- Coinbase对JWT的字段有没有文档未提及的隐藏校验规则?比如是否要求某些字段的格式、长度限制?
如果各位有过类似的踩坑经验,或者能指出我代码里的问题,麻烦帮忙解答一下,非常感谢!




