#c# #oauth #twitter-oauth
#c# #oauth #twitter-oauth
Вопрос:
Я следовал инструкциям на http://dev.twitter.com/pages/auth#request-token и разработал класс c # для выполнения авторизации OAuth. Я использовал параметры на странице, и базовая строка выходной подписи и подпись совпадают с таковыми на странице. Поэтому я думаю, что часть алгоритма верна. Затем я заменил параметры на те, что были в моем приложении Twitter, но мне не удалось получить токен запроса от службы Twitter. И данные ответа «Не удалось проверить подпись и токен oauth».
Вот запрос, который я отправляю (я использовал http вместо https для отладки):
POST http://api.twitter.com/oauth/request_token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: OAuth oauth_callback="http://localhost:3005/the_dance/process_callback?service_provider_id=11", oauth_consumer_key="GDdmIQH6jhtmLUypg82g", oauth_nonce="QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1272323042", oauth_version="1.0", oauth_signagure="IP/EEoc4tKdiobM/KH5cPK69cJM="
Host: api.twitter.com
Proxy-Connection: Keep-Alive
И вот ответ:
HTTP/1.1 401 Unauthorized
Connection: Keep-Alive
Connection: Proxy-Support
Content-Length: 44
Via: 1.1 APS-PRXY-09
Expires: Tue, 31 Mar 1981 05:00:00 GMT
Date: Fri, 08 Apr 2011 05:47:20 GMT
Content-Type: text/html; charset=utf-8
Server: hi
Proxy-Support: Session-Based-Authentication
Status: 401 Unauthorized
X-Transaction: 1302241640-40339-46793
Last-Modified: Fri, 08 Apr 2011 05:47:20 GMT
X-Runtime: 0.01519
Pragma: no-cache
X-Revision: DEV
Cache-Control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
Set-Cookie: k=207.46.55.29.1302241640766556; path=/; expires=Fri, 15-Apr-11 05:47:20 GMT; domain=.twitter.com
Set-Cookie: guest_id=13022416407746962; path=/; expires=Sun, 08 May 2011 05:47:20 GMT
Set-Cookie: _twitter_sess=BAh7CDoPY3JlYXRlZF9hdGwrCEiBpjMvAToHaWQiJWMzMTViOGZiNDkzMDRi%250ANjNhMmQwYmVkZDBhNTc2NTc4IgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVy%250AOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--177afd5c0f6fe30005ab9a9412e6f85ab03cbfa7; domain=.twitter.com; path=/; HttpOnly
Vary: Accept-Encoding
Failed to validate oauth signature and token
Вот как я генерирую нормализованные параметры:
string.Join("amp;", (from d in this.BuildParameterDict()
select string.Format("{0}={1}", OAuthEncoding.Encode(d.Key), OAuthEncoding.Encode(d.Value))))
Метод BuildParameterDict отсортирует список, содержащий: параметры из строки запроса; параметры из тела; параметры, определенные для ‘oauth’, за исключением ‘oauth_signature’.
Затем базовая строка подписи генерируется:
StringBuilder sb = new StringBuilder();
sb.Append(OAuthEncoding.Encode(this._request.Method));
sb.Append('amp;');
sb.Append(OAuthEncoding.Encode(this.GetNormalUri()));
sb.Append('amp;');
sb.Append(OAuthEncoding.Encode(this.GetNormalParameters()));
Это сгенерированная базовая строка с параметрами со страницы выше:
POSTamp;https://api.twitter.com/oauth/request_tokenamp;oauth_callback=http%3A%2F%2Flocalhost%3A3005%2Fthe_dance%2Fprocess_callback%3Fservice_provider_id%3D11&oauth_consumer_key=GDdmIQH6jhtmLUypg82g&oauth_nonce=QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1272323042&oauth_version=1.0
который идентичен строке на этой странице.
Комментарии:
1. Параметры oauth являются параметрами запроса, они не отображаются в заголовке авторизации. Поместите их под заголовками.
2. Но в соответствии с этим я могу использовать заголовок ‘Authorization’. Кроме того, я пытался поместить их в тело, тоже не работает…
3. ваша базовая строка, похоже, в порядке. как насчет вашего хеширования? что вы используете при создании своей подписи? ключ должен быть сконструирован из OAUTH_CONSUMER_SECRET и OAUTH_TOKEN. даже если токен отсутствует, ключ должен иметь amp; в конце (код PHP):
$KEY = $OAUTH_CONSUMER_SECRET.'amp;'.$OAUTH_TOKEN;
чем подпись$OAUTH_SIGNATURE = base64_encode(hash_hmac('sha1', $BASE_STRING, $KEY, true));
… Я предполагаю, что у вас проблема с подписью.4. кроме того, создаваемая вами строка выглядит «точно» такой же, как в примере Twitter. вы не создаете одноразовый номер и временную метку самостоятельно? вы используете строки, написанные от руки? вы должны указать временную метку как unixtime, а одноразовый номер должен быть случайным. что-то вроде md5, хэширующего случайное большое число…
5. Да, о ‘amp;’ позаботились. В приведенном выше коде я жестко закодировал ‘timespan’ и ‘nonce’, на практике они заменяются правильным значением.
Ответ №1:
Ваша подпись oauth указана в вашем запросе как «oauth_signagure».
Параметры OAuth должны быть отсортированы перед отправкой, но подпись должна быть в конце запроса на авторизацию. (9.1.1 в http://oauth.net/core/1.0/#anchor14)
Вам также может потребоваться указать область=»/oauth/request_token». Это необязательно, но, насколько я правильно помню, Twitter хочет этот токен для запроса.
Если вы сможете добавить свой код, мы могли бы выяснить, что происходит, поскольку вы, возможно, неправильно создаете свой запрос и ключ для хэширования подписи.
Комментарии:
1. Спасибо, что нашли эту опечатку 🙂 Я добавлю некоторый фрагмент кода к исходному сообщению.
2. Да, вы правы. ‘oauth_signature’ должен быть последним. Но здесь это не упоминается, и пример даже неправильный… Я ненавижу Twitter: (