使用 PHP cURL GET 在 Netsuite 中使用 HMAC-SHA256 进行 Oauth

Oauth with HMAC-SHA256 in Netsuite using PHP cURL GET

我已经无计可施了... 我有一个有效的 node.js 实现,并试图在 PHP 中做同样的事情 我有 运行 到墙上。我检查了硬编码的 nonce 和时间戳值,并在 node.js 和 PHP 中获得了完全相同的签名,但来自带有 PHP 的 Netsuite 的 return 值仍然是 "{"error" : {"code" : "INVALID_LOGIN_ATTEMPT", "message" : "Invalid login attempt."}}"而 javascript 版本,具有完全相同的签名和 headers returns 有效数据。

授权 header 在 node.js 和 PHP 中看起来完全一样,但在 PHP 中它总是 return 和 INVALID_LOGIN_ATTEMPT。 ..

下面的代码是从随处可见的几个示例拼接而成的。

    $httpMethod ="GET"; 
    $projectid = "xxx";
    $taskid = "xxx";
    $script = "xxx";
    $accountID = 'xxxxx-sb1';
    $realm = "xxxxx_SB1";
    $url = 'https://'.$accountID.'.restlets.api.netsuite.com/app/site/hosting/restlet.nl';
    $url_params = "?script=$script&deploy=1&taskid=$taskid&projectid=$projectid";
    $ckey = "xxxxx"; //Consumer Key
    $csecret = "xxxxx"; //Consumer Secret
    $tkey = "xxxxx"; //Token ID
    $tsecret = "xxxxx"; //Token Secret
    $timestamp= time();
    $nonce= uniqid(mt_rand(1, 1000));
    $baseString = $httpMethod . '&' . rawurlencode($url) . "&"
        . rawurlencode("oauth_consumer_key=" . rawurlencode($ckey)
            . "&oauth_nonce=" . rawurlencode($nonce)
            . "&oauth_signature_method=HMAC-SHA256"
            . "&oauth_timestamp=" . rawurlencode($timestamp)
            . "&oauth_token=" . rawurlencode($tkey)
            . "&oauth_version=1.0"
            . "&projectid=" . rawurlencode($projectid) 
            . "&script=" . rawurlencode($script) 
            . "&taskid=" . rawurlencode($taskid) 
        );
        $key = rawurlencode($csecret) . '&' . rawurlencode($tsecret);

        $signature = rawurlencode(base64_encode(hash_hmac('sha256', $baseString, $key, true)));
        echo "signature: $signature\n\n";
        $header = array(
            "Content-Type: application/json",
            "Authorization: OAuth realm=\"$realm\", oauth_consumer_key=\"$ckey\", oauth_token=\"$tkey\", oauth_nonce=\"$nonce\", oauth_timestamp=\"$timestamp\", oauth_signature_method=\"HMAC-SHA256\", oauth_version=\"1.0\", oauth_signature=\"$signature\"",
        );

        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_URL => $url . $url_params,
            CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0',
            CURLOPT_SSL_VERIFYPEER => 0,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => $httpMethod,
            CURLOPT_HTTPHEADER => $header,
        ));

        $response = curl_exec($curl);

        curl_close($curl);

        var_dump($response);

    }```

很确定你的领域应该是:

$realm = "xxxxx_SB1"; // 下划线不是破折号

感谢@bknights,我终于找到了正确的解决方案。我还缺少 deploy=1 -参数并且领域需要下划线而不是连字符。

我真的花了两天时间在这上面...

    $projectid = "xxx";
    $taskid = "xxx";
    $script = "xxx";
    $accountID = 'xxx-sb1';
    $realm = "xxx_SB1";//NOTICE THE UNDERSCORE
    $url = 'https://'.$accountID.'.restlets.api.netsuite.com/app/site/hosting/restlet.nl';
    $url_params = "?script=$script&deploy=1&taskid=$taskid&projectid=$projectid";
    $ckey = "ccccc"; //Consumer Key
    $csecret = "sssss"; //Consumer Secret
    $tkey = "ttttt"; //Token ID
    $tsecret = "sssss"; //Token Secret    
    $timestamp= time();
    $nonce=  uniqid(mt_rand(1, 1000));
    $baseString = $httpMethod . '&' . rawurlencode($url) . "&"
        . rawurlencode("deploy=1&oauth_consumer_key=" . rawurlencode($ckey)
            . "&oauth_nonce=" . rawurlencode($nonce)
            . "&oauth_signature_method=HMAC-SHA256"
            . "&oauth_timestamp=" . rawurlencode($timestamp)
            . "&oauth_token=" . rawurlencode($tkey)
            . "&oauth_version=1.0"
            . "&projectid=" . rawurlencode($projectid) 
            . "&script=" . rawurlencode($script) 
            . "&taskid=" . rawurlencode($taskid) 
);
        $key = rawurlencode($csecret) . '&' . rawurlencode($tsecret);
        $signature = rawurlencode(base64_encode(hash_hmac('sha256', $baseString, $key, true)));
        $header = array(
            "Authorization: OAuth realm=\"$realm\", oauth_consumer_key=\"$ckey\", oauth_token=\"$tkey\", oauth_nonce=\"$nonce\", oauth_timestamp=\"$timestamp\", oauth_signature_method=\"HMAC-SHA256\", oauth_version=\"1.0\", oauth_signature=\"$signature\"",
            "Content-Type: application/json"
        );

        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_URL => $url . $url_params,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => $httpMethod,
            CURLOPT_HTTPHEADER => $header,
        ));

        $response = curl_exec($curl);

        curl_close($curl);

        var_dump($response);```