首页 > 解决方案 > 使用 sha512、base64、UTC 时间戳和 Javascript/Node 的 API 授权

问题描述

我正在尝试访问我们的支付提供商 API,但我不断收到 403 响应(禁止)。我已经三重检查了凭据,它们是正确的。以下是认证说明:

对 API 的每个请求都必须使用 Authorization HTTP 请求标头进行身份验证。

将时间戳放在“时间戳”标题中。该值应该是创建和发送消息的时间,以 UTC 表示。

使用以下公式为每个请求计算授权标头。

base64 ({MerchantId}: sha512 (RequestBody + SecretWord + Timestamp))

例子:

'Timestamp': 2016-11-16 13:21:02

'Authorization': Svea TQ1Q0MzNDJERkQxRDRDRTgxQzM2NjNGRjAwMTg3RTE3M0NDNg==

完整的文档在这里

这是我得到的代码:

import axios from "axios";
import CryptoJS from "crypto-js";

// Below function returns the date in the following format "#YYYY#-#MM#-#DD# #hh#:#mm#:#ss#" in UTC time. 
//Code for customFormat is omitted but it returns a string in the expected for`enter code here`mat.
 
      function customDate() {
        let now = new Date();
        return now.customFormat("#YYYY#-#MM#-#DD# #hh#:#mm#:#ss#");
      }

      let timeStamp = customDate();
      let id = 123456; //Not the actual id, but same format (6 digits).
      let secret = "AaBb123C345De"; //Not the actual secret. Actual secret is a long string of digits and letters
      let body = "";

      let hashString = CryptoJS.SHA512(
        `${body}${secret}${timeStamp}`
      ).toString();

      hashString = hashString.replace(/\-/, "");

      console.log(timeStamp);

      axios
        .get(
          "https://paymentadminapi.svea.com/api/v1/orders/123",
          {
            headers: {
              "Timestamp": timeStamp,
              "Authorization": "Svea " + btoa(`${id}:${hashString}`),
            },
          }
        )
        .then((res) => {
          console.log(res.data);
        })
        .catch((error) => {
          console.error(error);
        });

这应该得到一个特定的订单号(在此示例代码中为 123),但它不起作用(响应 403),所以谁能告诉我我做错了什么?谢谢!

标签: node.jsauthenticationaxioscryptojs

解决方案


我想到了。简单的人为错误。customDate 以这种格式返回今天的日期,2021-05-25 08:20:02但这是预期的格式,2021-5-25 8:20:2. 当数字小于 10 时为个位数。

我用这个替换了 customDate 函数:

      const now = new Date();
      const year = now.getUTCFullYear();
      const month = now.getUTCMonth() +1; // January = 0
      const day = now.getUTCDate();
      const hour = now.getUTCHours();
      const minute = now.getUTCMinutes();
      const sec = now.getUTCSeconds();

      const timeStamp = `${year}-${month}-${day} ${hour}:${minute}:${sec}`;

现在它起作用了。也许有更好的方法来获取特定 UTC 格式的日期,但这对我有用。


推荐阅读