Я пытался заставить приложение PHP подключаться к сервисам Instaa Xauth, но я не могу заставить его работать. Я продолжаю получать «403: Неверная подпись». ошибка.
Ошибка говорит о том, что моя базовая строка сигнатуры не соответствует ожидаемой, но когда я сравниваю базовую строку сигнатуры, которую я создаю, с тем, что, как они говорят, они ожидают, они точно такие же (удаленная конфиденциальная информация):
Моя базовая строка подписи:
СООБЩЕНИЕ&HTTPS% 3A% 2F% 2Fwww.instapaper.com% 2Fapi% 2F1% 2Foauth% 2Faccess_token&oauth_callback% 3DMy_URL% 26oauth_consumer_key% 3DCONSUMER_KEY% 26oauth_nonce% 3Dfe379af261aca07d890d2cfaa0f19ce0% 26oauth_signature_method% 3DHMAC-SHA1% 26oauth_timestamp% 3D1461898452% 26oauth_version% 3D1.0% 26x_auth_mode% 3Dclient_auth% 26x_auth_password% 3DPASSWORD% 26x_auth_username% 3DEXAMPLE% 2540gmail.com
Что ошибка говорит, что ожидает:
СООБЩЕНИЕ&HTTPS% 3A% 2F% 2Fwww.instapaper.com% 2Fapi% 2F1% 2Foauth% 2Faccess_token&oauth_callback% 3DMy_URL% 26oauth_consumer_key% 3DCONSUMER_KEY% 26oauth_nonce% 3Dfe379af261aca07d890d2cfaa0f19ce0% 26oauth_signature_method% 3DHMAC-SHA1% 26oauth_timestamp% 3D1461898452% 26oauth_version% 3D1.0% 26x_auth_mode% 3Dclient_auth% 26x_auth_password% 3DPASSWORD% 26x_auth_username% 3DEXAMPLE% 2540gmail.com
Я вытащил мою php-библиотеку из https://github.com/mheap/Instapaper-XAuth-PHP, но он старый, поэтому я попытался изменить его для работы с текущим Instapaper API. Я считаю, что я генерирую строку подписи правильно и следую инструкциям, найденным здесь: https://dev.twitter.com/oauth/overview/creating-signatures и здесь: http://oauthbible.com/
Я не знаю, что не так с кодом, может кто-нибудь помочь?
class XAuth_Connection
{
private $_headers = array(
"oauth_signature_method" => "HMAC-SHA1",
"oauth_version" => "1.0",
"oauth_callback" => "MY_URL",
"oauth_consumer_key" => "",
"oauth_nonce" => "",
"oauth_timestamp" => "");
private $_params = array(
"x_auth_mode" => "client_auth",
"x_auth_username" => "",
"x_auth_password" => "");
private $_access_url = '';
public function __construct($key, $private, $access_url)
{
$this->_headers['oauth_consumer_key'] = $key;
$this->_headers['oauth_nonce'] = md5(uniqid(rand(), true));
$this->_headers['oauth_timestamp'] = time();
$this->_oauth_consumer_private = $private;
$this->_access_url = $access_url;
}
public function set_credentials($user, $password)
{
$this->_params['x_auth_username'] = $user;
$this->_params['x_auth_password'] = $password;
}
public function get_params_as_string()
{
ksort($this->_params);
$req = array();
foreach ($this->_params as $k => $v)
{
$req[] = $k ."=". $this->encode($v);
}
return implode("&", $req);
}
public function get_headers_as_string()
{
ksort($this->_headers);
$req = array();
foreach ($this->_headers as $k => $v)
{
$req[] = $k . "=" . $this->encode($v);
}
return implode("&", $req);
}
public function generate_signature()
{
//combine the parameters, encode, and sort them
$temp_params = array_merge($this->_params, $this->_headers);
$encoded_params = Array();
foreach($temp_params as $k => $v){
$encoded_params[$this->encode($k)] = $this->encode($v);
}
ksort($encoded_params);
//Build the param string
$param_base_string = "";
foreach($encoded_params as $k => $v){
$param_base_string .= $k .'='. $v . '&';
}
$param_base_string = rtrim($param_base_string, '&');
//create the signature base
$signature_base = 'POST&' . $this->encode($this->_access_url) .'&'. $this->encode($param_base_string);
$key = $this->encode($this->_oauth_consumer_private) . '&';
return base64_encode(hash_hmac("sha1",$signature_base, $key, true));
}public function login()
{$this->_headers['oauth_signature'] = $this->generate_signature();
ksort($this->_headers);
$header_str = 'OAuth ';
foreach ($this->_headers as $k => $v)
{
$header_str .= $k.'="'.$this->encode($v).'", ';
}
$header_str = rtrim($header_str, ', ');
$oauth_str = $this->get_params_as_string();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->_access_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $oauth_str);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: " . $header_str));
$exec = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
if ($info['http_code'] != 200)
{
return false;
}
parse_str($exec, $r);
return $r;
}
private function encode($s)
{
return ($s === false ? $s : str_replace('%7E','~',rawurlencode($s)));
}
}
Задача ещё не решена.
Других решений пока нет …