Nodejs Coinbase V2 REST 端点 returns 无效签名

Nodejs Coinbase V2 REST endpoint returns invalid signature

无法弄清楚为什么 coinbase v2 REST 端点 returns 出现无效签名错误,也许有人看出我做错了什么。我发现的所有内容都与使用不再维护的旧 NPM 包有关。还有一个Coinbase Pro包,但是我不想和Pro通信API。

const { createHmac } = require('crypto');
const axios = require('axios');

(async () => {

  const cbApiKey = 'xxx';
  const apiSecret = 'xxx';
  const method = 'GET';
  const path = '/v2/user';
  const body = '';
 
  const timestamp = Math.floor(new Date().getTime() * 1e-3);
  const message = timestamp + method + path + body;

  const key = Buffer.from(apiSecret, 'base64');
  const cbAccessSign = createHmac('sha256', key).update(message).digest('base64');

  const instance = axios.create();

  try {
    const user = await instance.request({
      method,
      url: `https://api.coinbase.com${path}`,
      headers: {
        'CB-ACCESS-KEY': `${cbApiKey}`,
        'CB-ACCESS-SIGN': `${cbAccessSign}`,
        'CB-ACCESS-TIMESTAMP': `${timestamp}`,
        "Content-Type": 'application/json',
      },
    }); 
    console.log(user);
  } catch (error) {
    console.log(error);
  }  
})();

我在这里找到了答案https://github.com/coinbase/coinbase-node/blob/master/lib/ClientBase.js#L101

签名的正确代码是

var signature = crypto.createHmac('sha256', this.apiSecret).update(message).digest('hex');

我要在这里添加一些东西,因为它早些时候让我发疯,即。尝试 crypto-js 无济于事,然后不得不进行大量斗争并采取一些变通办法,使 'crypto' 在教程中使用时可以解决它目前遇到的所有障碍。

据我所知,大多数无效签名都可以追溯到 CB-ACCESS-SIGN,最大的挑战是弄清楚 crypto-js 中的工作等价物是什么样的,并让所有这些在Angular10.

API 调用的精简版和访问标志的哈希字符串创建:

import * as CryptoJS from 'crypto-js';

async getUserCreds(apk: string, aps: string): Promise<any> {
  let access_sign = Access_Sign(getUnixTimestamp(), 'GET', '/v2/user','',aps)

  let httpOptions = {
    headers: new HttpHeaders({
      "CB-ACCESS-KEY": apk,
      "CB-ACCESS-SIGN": access_sign,
      "CB-ACCESS-TIMESTAMP": getUnixTimestamp().toString(),
      "Content-Type": "application/json"
    })
  }

  return this.http.get<any>('https://api.coinbase.com/v2/user',httpOptions)
    .pipe(shareReplay(), catchError((x) => { return this.handleErrorLog(x) 
    })).toPromise();
}


export function Access_Sign(timestamp: number, method: string, requestPath: string, body: string, secret: string) {

  let prehash = timestamp + method.toUpperCase() + requestPath + body;
  return CryptoJS.HmacSHA256(prehash, secret).toString(CryptoJS.enc.Hex);
}

export function getUnixTimestamp() {
  return Math.floor(Date.now() / 1000)
}