Я использую протокол OAuth 1.0 для подключения к службе контактов Google и получения всех контактов пользователя. Когда я запрашиваю токен запроса, один из трех раз я получаю ответ «signature_invalid» с серверов Google. Как это возможно: один и тот же код работает много раз, а иногда нет? Если кто-то хочет попробовать, вот его тестовая страница: http://www.spats.in/nssc2/gmailContactsImport.php. В первых строках она печатает построенную мной базовую строку. Во второй строке печатается ответ от сервера. В третьей строке он печатает секрет запроса, если он получает его с сервера, в противном случае - его бред. Попробуйте перезагрузить страницу несколько раз; Вы определенно получите ответ signature_invalid несколько раз.
Сохранится ли эта проблема, и я должен позаботиться о том, чтобы внести изменения в мой код для повторной отправки запроса в случае получения отрицательного ответа или я делаю что-то не так?
Вот мой код, если кто-то захочет взглянуть на него:
$_SESSION['uid']=31; // Just set to something for checking
$consumer_key="www.spats.in";
$secret="***********************"; //I've hidden it
$mt = microtime();$rand = mt_rand(); $nonce = md5($mt.$rand);
$time=time();
$key=urlencode(utf8_encode($secret))."&";
$url="https://www.google.com/accounts/OAuthGetRequestToken";
$params="oauth_callback=".urlencode("http://www.spats.in/nssc2/gmailContactsImport.php").
"&oauth_consumer_key=$consumer_key".
"&oauth_nonce=$nonce".
"&oauth_signature_method=HMAC-SHA1".
"&oauth_timestamp=".$time.
"&oauth_version=1.0".
"&scope=".urlencode("https://www.google.com/m8/feeds/");
$base_string = "GET&".urlencode($url).'&'.rawurlencode($params);
$signature = base64_encode(hash_hmac('sha1', $base_string, $key, true));
//Send off request
$params.="&oauth_signature=".$signature;
$result=file_get_contents($url."?".$params);
//Parse the result
$tokens=explode("&",$result);
$pos['oauth_token']=strpos($tokens[0],"=")+1;
$oauth_token=substr($tokens[0],$pos['oauth_token']);
$pos['oauth_secret']=strpos($tokens[1],"=")+1;
$oauth_secret=substr($tokens[1],$pos['oauth_secret']);
//Save request secret
$num=mysql_query("INSERT INTO google_auth_tokens (id,request_token_secret) values($_SESSION[uid],'$oauth_secret')");
$authorizeURL="https://www.google.com/accounts/OAuthAuthorizeToken";
header("Location:".$authorizeURL."?oauth_token=".$oauth_token);
ОБНОВЛЕНО: Как вы можете видеть, если вы посещаете страницу, о которой я упоминал выше, и получаете сообщение об ошибке, базовая строка, созданная мной и Google, точно совпадает каждый раз, так что это может означать, что может быть некоторая проблема с тем, как я подписываю базу строка. Я не могу уловить проблему в этом. Может ли кто-нибудь обнаружить какие-либо проблемы в этом?
ОБНОВЛЕНО: Вот две базовые строки: первая сгенерировала ответ «signature_invalid», а вторая прошла и вернула токен запроса:
GET&https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetRequestToken&oauth_callback%3Dhttp%253A%252F%252Fwww.spats.in%252Fnssc2%252FgmailContactsImport.php%26oauth_consumer_key%3Dwww.spats.in%26oauth_nonce%3D57e4656240c67b1e6a5bcbd5f9ecb2cf%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1308856148%26oauth_version%3D1.0%26scope%3Dhttps%253A%252F%252Fwww.google.com%252Fm8%252Ffeeds%252F
GET&https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetRequestToken&oauth_callback%3Dhttp%253A%252F%252Fwww.spats.in%252Fnssc2%252FgmailContactsImport.php%26oauth_consumer_key%3Dwww.spats.in%26oauth_nonce%3D734bab3909fea245a2ebcfefcea36c54%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1308856162%26oauth_version%3D1.0%26scope%3Dhttps%253A%252F%252Fwww.google.com%252Fm8%252Ffeeds%252F
Оба абсолютно одинаковы, за исключением параметров nonce и timestamp, которые должны различаться из-за отправки в разное время. Я не могу понять, почему один должен генерировать неверную подпись, а другой нет.