如何将我的工作 PHP 脚本转换为 CryptoJS 以访问远程 API?

How do I convert my working PHP script to CryptoJS to access a remote API?

我有以下 PHP 脚本,它可以完美地访问远程 REST api。最后,我按照 ?fromDate=2020-07-22 的方式给它一个查询,它会根据该响应生成最终的 URL,其中 returns 和 XML。我的问题是我试图将它转换为 Javascript 以便我可以让它在 Node 应用程序中工作(我是 Javascript 的新手并且对 JQuery 几乎一无所知!! ).我一辈子都无法让它工作。我认为问题在于将查询 fromDate 2020-07-22 传递到参数中,这是生成正确足迹所需的参数,该足迹需要包含在最终 REST api 请求中,以便它可以正确验证。

我在下面包含了原始的工作 PHP 脚本和我制作等效 JS 的努力。我已经为此工作了几个小时,我的大脑终于放弃了!

谁能看出我错在哪里?

<?php
$publicKey  = "insert public key here";
$privateKey = "insert private key here";
$url = 'https://www.api_endpoint.com/rest/1.0/reports?fromDate=2020-07-22';
$finalUrl = generateSignedUrl($url, $publicKey, $privateKey);
 
echo $finalUrl;
 
function generateSignedUrl($url, $publicKey, $privateKey) {
    $urlParts = parse_url($url);
    parse_str($urlParts['query'], $parameters);

    $parameters['myWebServiceID'] = $publicKey;
    $parameters['timeStamp'] = time();
    $parameters['footprint'] = generateFootPrint($privateKey, $parameters);
 
    return sprintf('%s://%s%s?%s', $urlParts['scheme'], $urlParts['host'], $urlParts['path'], http_build_query($parameters));
}
 
function generateFootPrint($privateKey, $parameters) {
    if (empty($parameters)) throw new InvalidArgumentException('Parameters cannot be null');
 
    $parameters["secretKey"] = $privateKey;
    unset($parameters["footprint"]);
    ksort($parameters);
    $queryString = http_build_query($parameters);
    return base64_encode(hash_hmac('sha1', $queryString, $privateKey, true));
}
?>

这是我的 JS 版本:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/core.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/hmac.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/sha1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/sha256.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/enc-base64.js"></script>
<script>
$( document ).ready(function() {

var url = 'https://www.api_endpoint.com/rest/1.0/reports?fromDate=2020-07-22'; //Where I append my query
var publicKey = 'insert public key here';
var secretKey = 'insert private key here';
var timestamp = Math.round(new Date().getTime()/1000);
      
var parametersToHmac = {
    "myWebServiceID": publicKey,
    "secretKey": secretKey,
    "timeStamp": timestamp,
    "fromDate": '2020-07-22' //Where I last attempted to insert the query manually
};

var stringParametersToHmac = jQuery.param(parametersToHmac);
var hash_hmac = CryptoJS.HmacSHA1(stringParametersToHmac, secretKey);
var base64 = hash_hmac.toString(CryptoJS.enc.Base64);
      
var finalResult = {
    "myWebServiceID": publicKey,
    "timeStamp": timestamp,
    "footprint": base64
};
      
var finalQueryParams = jQuery.param(finalResult);
var finalUrl = url + "?" + finalQueryParams;
console.log(finalUrl);

我尝试过手动输入查询并尝试过各种解析它的尝试,但我一直在努力解决需要将其插入何处以确保足迹生成正确且因此不会被端点拒绝的概念。

好吧,一旦你问了一个问题,它有助于澄清你做错了什么,这真是太神奇了。在 generateFootPrint 函数的 PHP 脚本中有一个 ksort 函数,它按字母顺序对 PHP 中的键进行排序。我在 Javascript.

的翻译中漏掉了这个

因此更改传递给 Hmac 的参数:

var parametersToHmac = {
    "myWebServiceID": publicKey,
    "secretKey": secretKey,
    "timeStamp": timestamp,
    "fromDate": '2020-07-22' //move this from here
};

至:

var parametersToHmac = {
    "fromDate": '2020-07-22', //to here!!
    "myWebServiceID": publicKey,
    "secretKey": secretKey,
    "timeStamp": timestamp
};

即按字母顺序排列,returns 与 PHP 脚本相同的足迹,并且当编译成 rest 时 URL 被端点接受并且 returns 需要数据。

感谢收听!