几个月前,我实现了一个RESTlet解决方案,该解决方案从PHP脚本接收POST请求。我现在正在扩展解决方案,以向具有不同ID的RESTlet发送GET请求。问题是只有在将请求发送到没有查询字符串的URL时,身份验证才会成功。我们需要将查询字符串传递给RESTlet才能执行。
将查询字符串附加到URL会引发403 INVALID_LOGIN错误,并且在没有它的情况下调用RESTlet会抛出缺少参数的异常(如预期的那样)。
private function setAuthentication() {
$oauthNonce = md5(mt_rand());
$oauthTimestamp = time();
$baseString = $this->requestType."&".urlencode($this->url)."&".urlencode(
"deploy=".$this->deployID
."&oauth_consumer_key=".$this->consumerKey
."&oauth_nonce=".$oauthNonce
."&oauth_signature_method=".$this->oauthSigMethod
."&oauth_timestamp=".$oauthTimestamp
."&oauth_token=".$this->tokenID
."&oauth_version=".$this->oauthVersion
."&realm=".$this->account
."&script=".$this->scriptID
);
$sigString = urlencode($this->consumerSecret).'&'.urlencode($this->tokenSecret);
$signature = base64_encode(hash_hmac('sha1', $baseString, $sigString, true));
$authHeader = "OAuth "
. 'oauth_signature="' . rawurlencode($signature) . '", '
. 'oauth_version="' . rawurlencode($this->oauthVersion) . '", '
. 'oauth_nonce="' . rawurlencode($oauthNonce) . '", '
. 'oauth_signature_method="' . rawurlencode($this->oauthSigMethod) . '", '
. 'oauth_consumer_key="' . rawurlencode($this->consumerKey) . '", '
. 'oauth_token="' . rawurlencode($this->tokenID) . '", '
. 'oauth_timestamp="' . rawurlencode($oauthTimestamp) . '", '
. 'realm="' . rawurlencode($this->account) .'"';
return $authHeader;
}
public function callGetRestlet() {
$this->requestType = 'GET';
$authorizationHeader = $this->setAuthentication();
$urlQueryAppend = http_build_query(array('id' => $this->queryString));
$ch = curl_init();
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->requestType);
curl_setopt($ch, CURLOPT_URL, $this->url. '?&script='. $this->scriptID. '&deploy='. $this->deployID.'&realm=' . $this->account);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: '.$authorizationHeader,
'Content-Type: application/json',
]);
$response = array();
$response['request'] = json_decode($this->queryString);
$response['response']['body'] = json_decode(curl_exec($ch));
$response['response']['code'] = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $response;
}
我知道凭据是可以的,因为RESTlet的事件日志在未提供参数时显示异常。以上抛出异常。
修改CURLOPT_URL以包含查询字符串时,它会抛出403:
curl_setopt($ch, CURLOPT_URL, $this->url. '?&script='. $this->scriptID. '&deploy='. $this->deployID.'&realm=' . $this->account.'&'.$urlQueryAppend);
此代码稍微修改了一个问题,询问有关POST请求的问题。
是否因设置请求标头而引发错误?
部署ID解决问题后,将id参数添加到基本字符串。我将它添加到最后,但在这种情况下,它看起来像参数的顺序很重要。
private function setAuthentication() {
$oauthNonce = md5(mt_rand());
$oauthTimestamp = time();
$baseString = $this->requestType."&".urlencode($this->url)."&".urlencode(
"deploy=".$this->deployID
."&id=".$this->queryString
."&oauth_consumer_key=".$this->consumerKey
."&oauth_nonce=".$oauthNonce
."&oauth_signature_method=".$this->oauthSigMethod
."&oauth_timestamp=".$oauthTimestamp
."&oauth_token=".$this->tokenID
."&oauth_version=".$this->oauthVersion
."&script=".$this->scriptID
);
$sigString = urlencode($this->consumerSecret).'&'.urlencode($this->tokenSecret);
$signature = base64_encode(hash_hmac('sha1', $baseString, $sigString, true));
$authHeader = "OAuth "
. 'oauth_signature="' . rawurlencode($signature) . '", '
. 'oauth_version="' . rawurlencode($this->oauthVersion) . '", '
. 'oauth_nonce="' . rawurlencode($oauthNonce) . '", '
. 'oauth_signature_method="' . rawurlencode($this->oauthSigMethod) . '", '
. 'oauth_consumer_key="' . rawurlencode($this->consumerKey) . '", '
. 'oauth_token="' . rawurlencode($this->tokenID) . '", '
. 'oauth_timestamp="' . rawurlencode($oauthTimestamp) . '", '
. 'realm="' . rawurlencode($this->account) .'"';
return $authHeader;
}
public function callGetRestlet() {
$this->requestType = 'GET';
$parameters = http_build_query(
array(
'script' => $this->scriptID,
'deploy' => $this->deployID,
'id' => $this->queryString,
)
);
$authorizationHeader = $this->setAuthentication();
$ch = curl_init();
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->requestType);
curl_setopt($ch, CURLOPT_URL, $this->url. '?'.$parameters);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 6);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: '.$authorizationHeader,
'Content-Type: application/json',
]);
$response = array();
$response['request'] = $this->url. '?'.$parameters;
$response['response']['body'] = json_decode(curl_exec($ch));
$response['response']['code'] = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $response;
}