几个月前,我实现了一个RESTlet解决方案,该解决方案从PHP脚本接收POST请求。我现在正在扩展解决方案,以将GET请求发送到具有不同ID的RESTlet。问题是仅当请求发送到没有查询字符串的URL时,身份验证才成功。我们需要将查询字符串传递给RESTlet才能执行。
将查询字符串附加到URL会引发403 INVALID_LOGIN错误,而调用RESTlet时如果没有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请求的问题的回答中稍作修改的。
设置请求标头是否引发了错误?
答案 0 :(得分:0)
在部署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;
}