【问题标题】:NodeJS equivalent of C# code for hmac-sha256 authorization用于 hmac-sha256 授权的 NodeJS 等效 C# 代码
【发布时间】:2018-03-26 15:36:04
【问题描述】:

我正在尝试转换此处找到的 C# 代码: AMX Authorization Header 以连接到外部 API。 C# 代码在尝试连接到外部 API 时有效,但当我将其转换为 nodeJS 解决方案时它不起作用。

我无权访问外部 C# API,因此无法更新该方面,但希望有人可以查看此内容并看到我遗漏或做错的事情:

我的nodejs解决方案:

var request = require('request');
var uuid = require('node-uuid');
var CryptoJS = require('crypto-js');

var URL = "https://urltoexternalAPI.com";
var itemAPPId = "testAPPId";
var APIKey = "testAPIKey";

var requestUri = encodeURIComponent(URL.toLowerCase());
var requestHttpMethod = "GET";

var requestTimeStamp = Math.floor(new Date().getTime() / 1000).toString();

var nonce = uuid.v1().replace(/-/g, '');

//I excluded the content hashing part as the API Im hitting is a GET request with no body content
var signatureRawData = itemAPPId + requestHttpMethod + requestUri + requestTimeStamp + nonce;

var secretKeyByteArray = CryptoJS.enc.Base64.parse(APIKey);

var signature = CryptoJS.enc.Utf8.parse(signatureRawData);

var signatureBytes = CryptoJS.HmacSHA256(signature, secretKeyByteArray);

var requestSignatureBase64String = signatureBytes.toString(CryptoJS.enc.Base64);

request({
  url: URL,
  headers: {
    'Authorization': "amx "+itemAPPId+":"+requestSignatureBase64String+":"+nonce+":"+requestTimeStamp
  }
}, function (error, response, body) {
  if (response.statusCode != 200) {
    console.log("Fail");
  } else {
    console.log("Success");
  }
});

【问题讨论】:

  • 你见过这个问题吗:stackoverflow.com/questions/7480158 ?
  • @Yoryo 我已经尝试过该解决方案,但它仍然返回未经授权的 401。我不知道这是否与他们解码它的方式有关,但我真的不希望有一个 c# 处理程序只是为了向外部 API 运行一个请求。我使用了您链接的问题的答案,如下所示:var requestSignatureBase64String = crypto.createHmac('sha256', APIKey).update(signatureRawData).digest('hex');

标签: javascript c# node.js hmac


【解决方案1】:

我想通了!如果有人遇到此问题,他们可能会发现以下内容很有帮助:

以下 C# 代码的工作方式与 nodeJS 略有不同: System.Web.HttpUtility.UrlEncode(request.RequestUri.AbsoluteUri.ToLower());

最初我按原样复制了这个功能并编写了等效的nodejs:

 var requestUri = encodeURIComponent(URL.toLowerCase());

C# 中 URL 的编码将所有内容保持为小写 - 例如:https:// 变为 https%3a%2f%2f - 而 nodeJS 将其编码大写字符 - https%3A%2F%2F - 这是导致不正确散列的原因。

解决方案是在 URL 上完成编码后将小写函数移动到。像这样:

var requestUri = encodeURIComponent(URL).toLowerCase();

看起来相当简单,但在尝试复制 C# 解决方案时,您可能不会发现两个 URL 编码器的工作方式不同。

最终解决方案:(感谢Yoryo,更新为加密)

const fetch = require("node-fetch");
const uuid = require("uuid");
const crypto = require('crypto');

var URL = "https://urltoapi.com";

var itemAPPId = config.itemAPPId;
var APIKey = config.itemAPIKey;

var requestUri = encodeURIComponent(URL).toLowerCase();
var requestHttpMethod = "GET"; //should be dynamic

var requestTimeStamp = Math.floor(new Date().getTime() / 1000).toString();

var nonce = uuid.v1().replace(/-/g, '');
var signatureRawData = itemAPPId + requestHttpMethod + requestUri + requestTimeStamp + nonce;

var key = Buffer.from(APIKey, 'base64');
var requestSignatureBase64String = crypto.createHmac('sha256', key).update(signatureRawData, 'utf8').digest('base64');

const hitExternalAPI = async url => {
  try {
    const res = await fetch(url, { method: 'GET', headers: { "Authorization": "amx "+itemAPPId+":"+requestSignatureBase64String+":"+nonce+":"+requestTimeStamp } })
    .then(res => {
      console.log(res.ok);
    });
  } catch (error) {
    console.log("Error",error);
  }
};
hitExternalAPI(URL);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 2020-10-18
    • 2017-02-07
    • 2016-01-29
    相关资源
    最近更新 更多