使用 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);```
我已经无计可施了...
我有一个有效的 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);```