非专业版CoinBase API调用出现Invalid Signature签名错误如何解决
Coinbase非专业版API返回invalid signature错误的常见原因及修复方案
你当前使用的是Coinbase Pro的签名逻辑对接普通Coinbase v2 API,二者认证规则存在差异,常见疏漏点如下:
- 遗漏CB-VERSION请求头:普通Coinbase v2 API强制要求携带
CB-VERSION头,取值为格式为YYYY-MM-DD的API版本号(建议使用近期日期,如2023-01-01),Coinbase Pro无此要求,这是最常见的报错原因。 - 未传入CB-ACCESS-PASSPHRASE头:你提到此前Pro版本代码添加了passphrase可正常运行,但当前代码的请求头中未包含
CB-ACCESS-PASSPHRASE字段,普通版API同样需要传递该参数,值为你创建API密钥时设置的passphrase。 - 密钥不通用:Coinbase Pro(现Coinbase Advanced)的API密钥与普通Coinbase平台的API密钥不互通,需确认你使用的密钥是在普通Coinbase平台「设置-API权限」中创建的,且已经开通了对应接口的访问权限(如获取账户列表需要开通
wallet:accounts:read权限)。 - 本地时间戳偏差过大:Coinbase要求请求头中的时间戳与Coinbase服务器时间偏差不能超过30秒,本地时钟不准会导致签名校验失败,可先调用
https://api.coinbase.com/v2/time接口获取服务器时间,再用于签名和请求头。 - 签名拼接逻辑差异:若后续使用POST请求,需确认body拼接的是序列化后的完整JSON字符串,不可传空值;如果GET请求携带查询参数,需要把完整的查询参数拼接在requestPath后再参与签名,和Pro版规则一致。
修复后的参考代码
const crypto = require('crypto'); require('dotenv').config(); const signedMessages = async (timestamp, meth, requestPath, body = '') => { const secret = process.env.cb_all_read_secret; const method = meth.toUpperCase(); const message = timestamp + method + requestPath + body; const key = Buffer.from(secret, 'base64'); const hmac = crypto.createHmac('sha256', key); return hmac.update(message).digest('base64'); }; const listAccounts = async () => { // 可选:优先获取Coinbase服务器时间避免偏差 // const timeRes = await fetch('https://api.coinbase.com/v2/time'); // const { epoch } = await timeRes.json(); // const timestamp = epoch; const timestamp = Math.floor(Date.now() / 1000); const requestPath = '/v2/accounts'; const signed = await signedMessages(timestamp, 'GET', requestPath); const url = 'https://api.coinbase.com' + requestPath; const options = { method: 'GET', headers: { 'Content-Type': 'application/json', 'CB-ACCESS-KEY': process.env.cb_all_read_key, 'CB-ACCESS-SIGN': signed, 'CB-ACCESS-TIMESTAMP': timestamp, 'CB-ACCESS-PASSPHRASE': process.env.cb_all_read_passphrase, // 新增passphrase头 'CB-VERSION': '2023-01-01' // 新增版本号头 }, }; try { const data = await fetch(url, options); const resultat = await data.json(); console.log(resultat); } catch (error) { console.log('error: ', error.message); } }; listAccounts();
内容的提问来源于stack exchange,提问作者Caligulaaa
相关产品推荐
相关产品推荐

