You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用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.com
  • nbf设为当前时间,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)

几个疑问点

  1. 是不是subiss字段的取值有特殊要求?我现在把两者都设为密钥的name,是否符合Coinbase的校验逻辑?
  2. 加载PEM私钥的方式有没有潜在问题?比如序列化的过程是否需要额外配置?
  3. Coinbase对JWT的字段有没有文档未提及的隐藏校验规则?比如是否要求某些字段的格式、长度限制?

如果各位有过类似的踩坑经验,或者能指出我代码里的问题,麻烦帮忙解答一下,非常感谢!

火山引擎 最新活动