Твиттер собственными руками на C#. Часть 1: авторизация OAuth


В один момент сложилась желание написать программу клиент для сетей микроблогинга Twitter, языком программирования был выбран C#.
Напомню что OAuth это открытый протокол авторизации, который позволяет предоставить третьей стороне доступ к защищенным ресурсам пользователя, без необходимости передавать ей (третьей стороне) логин и пароль. Третьим лицом в данном случае естественно будем являтся мы со своим приложением.
В принципе это руководство подойдёт для OAuth авторизации не только в Twitter, но и в любом другом портале который использует OAuth, например небезызвестный FriendFeed.

Сам процесс авторизации по протоколу OAuth довольно подробно рассмотрен на Хабре.
Для того что бы авторизоваться учётной записью твиттера нам надо зарегистрировать своё приложение в Twitter Developers.
Заполняем анкетку и нажимаем кнопку Register application, дальше вас перекинет на страницу приложения. На ней нас интересует две строки, а именно Consumer key и Consumer secret — их нам необходимо каким-либо образом сохранить потому что скоро они нам понадобятся.
А теперь немного теорий. По сути процесс авторизации условно можно разделить на три этапа:
1. Делаем запрос на api.twitter.com/oauth/request_token с целью получить первоначальные значения oauth_token и oauth_secret
2. Получив эти значения делаем ещё один запрос в окне браузера, но уже на api.twitter.com/oauth/authorize и пользователю будет предложено ввести свои логин/пароль от учётной записи твиттера, а далее ещё одна форма в которой будет сообщено что наше расчудесное приложение хочет использовать данные учётной записи пользователя и естественно две кнопки: для отказа и поодтверждения. При нажатии на кнопку подтверждения откроется страница на которой будет написан PIN-код. PIN-код пользователь должен передать нашему приложению.
3. И после того как пользователь введёт PIN-код в нашем приложении, мы должны будем сделать третий запрос на api.twitter.com/oauth/access_token для получения oauth_token и oauth_secret которые должны использоваться для идентификация пользователя в системе.
Будем делать всё последовательно и к концу статьи у нас должно получиться приложение которое сможет проходить OAuth авторизацию.
Теперь переходим к самому процессу написания програмы.
Создадим новое консольное приложение.
Итак, сперва мы должны сделать некий запрос приблизительно такого вида api.twitter.com/oauth/request_token?oauth_consumer_key=<?>&oauth_signature_method=<?>&oauth_signature=<?>&oauth_timestamp=<?>&oauth_nonce=<?>&oauth_version=<?>
Там где проставлены <?> должны быть ваши значения. Для получения некоторых значений я воспользовался небольшим, но очень удачным классом OAuthBase.cs
Скачиваем его и кладём в папку с приложением.

Так как мы будем делать запросы и работать с только что скачанным классом, то в заголовке программы у нас должны быть такие строки:
using System;
using OAuth;
using System.Net;
using System.IO;
using System.Text;


* This source code was highlighted with Source Code Highlighter.


Теперь нам надо сформировать строку запроса, присвоим её значение в переменную строкового типа request_url и осуществим первый запрос.

// Создадим три переменные и присвоим им значения данных полученных на сайте твиттера:
Uri uri = new Uri("http://api.twitter.com/oauth/request_token");
string consumerKey = "ваше значение consumerKey";
string consumerSecret = "ваше значение consumerSecret";
// Теперь нам нужно сгенерировать значения оставшихся переменных и именно для этого нам нужен будет класс OAuthBase
OAuthBase oAuth = new OAuthBase();
// Генерация необходимых данных
string timeStamp = oAuth.GenerateTimeStamp();
string nonce = oAuth.GenerateNonce();
string normUri;
string normParams;
string sig = oAuth.GenerateSignature(uri, consumerKey, consumerSecret, string.Empty, string.Empty, "GET", timeStamp, nonce, OAuth.OAuthBase.SignatureTypes.HMACSHA1, out normUri, out normParams);
// Формирование и вывод строки запроса
string request_url =
  "http://api.twitter.com/oauth/request_token"+"?" +
  "oauth_consumer_key=" + consumerKey + "&" +
  "oauth_signature_method=" + "HMAC-SHA1" + "&" +
  "oauth_signature=" + sig + "&" +
  "oauth_timestamp=" + timeStamp + "&" +
  "oauth_nonce=" + nonce + "&" +
  "oauth_version=" + "1.0";
Console.WriteLine("Req: " + request_url); // Выводим строку на экран
Console.WriteLine("--------------------------------------------------------");
// Запрос на сервер    
HttpWebRequest Request = (HttpWebRequest) HttpWebRequest.Create(request_url);
HttpWebResponse Response = (HttpWebResponse)Request.GetResponse();      
StreamReader Reader = new StreamReader(Response.GetResponseStream(), Encoding.GetEncoding(1251));
string outline = Reader.ReadToEnd();  
Console.WriteLine("Out: " + outline);
Console.WriteLine("--------------------------------------------------------");
// Разбор выданной строки
char[] delimiterChars = { '&', '=' };
string[] words = outline.Split(delimiterChars);
string oauth_token = words[1];
string oauth_token_secret = words[3];
string oauth_callback_confirmed = words[5];
// Вывод поллученных данных  
Console.WriteLine("oauth_token = " + oauth_token);  
Console.WriteLine("oauth_token_secret = " + oauth_token_secret);  
Console.WriteLine("oauth_callback_confirmed = " + oauth_callback_confirmed);
Console.WriteLine("--------------------------------------------------------");


* This source code was highlighted with Source Code Highlighter.


Теперь можно переходить ко второму шагу, на котором пользователю будет предложено ввести ПИН-код

// Строка открыв которую в браузере пользователю предложат открыть доступ к его учётке для приложения
// При положительном ответе на экран ивыдадут PIN код который надо вбить в приложении
request_url = "http://api.twitter.com/oauth/authorize?oauth_token="+ oauth_token;
Console.WriteLine("Req: " + request_url);
Console.WriteLine("--------------------------------------------------------");
System.Diagnostics.Process.Start(request_url); // Передаём ссылку на страницу браузеру по умолчанию и ждём пока пользователь введёт PIN-код
Console.Write("Enter PIN: ");
string oauth_verifier = Console.ReadLine(); // oauth_verifier — это полученный нами PIN-код.
Console.WriteLine("--------------------------------------------------------");


* This source code was highlighted with Source Code Highlighter.


И заключительный запрос, ответ на который мы должны будем сохранить и получим доступ к данным учётной записи

// Формирование и вывод строки запроса
request_url =
  "http://api.twitter.com/oauth/access_token"+"?" +
  "oauth_consumer_key=" + consumerKey + "&" +
  "oauth_token=" + oauth_token + "&" +
  "oauth_signature_method=" + "HMAC-SHA1" + "&" +
  "oauth_signature=" + sig + "&" +
  "oauth_timestamp=" + timeStamp + "&" +
  "oauth_nonce=" + nonce + "&" +
  "oauth_version=" + "1.0" + "&" +
  "oauth_verifier=" + oauth_verifier;
Console.WriteLine("Req: " + request_url);
Console.WriteLine("--------------------------------------------------------");
// Запрос на сервер
Request = (HttpWebRequest) HttpWebRequest.Create(request_url);
Response = (HttpWebResponse)Request.GetResponse();  
Reader = new StreamReader(Response.GetResponseStream(), Encoding.GetEncoding(1251));
outline = Reader.ReadToEnd();  
Console.WriteLine("Out: " + outline);
Console.WriteLine("--------------------------------------------------------");
// Разбор выданной строки и присвоение значений соответствующим переменным
words = outline.Split(delimiterChars);
oauth_token = words[1];
oauth_token_secret = words[3];
string user_id = words[5];
string screen_name = words[7];
// Вывод полученных данных  
Console.WriteLine("oauth_token = " + oauth_token);  
Console.WriteLine("oauth_token_secret = " + oauth_token_secret);  
Console.WriteLine("user_id = " + user_id);
Console.WriteLine("screen_name = " + screen_name);


* This source code was highlighted with Source Code Highlighter.


Вот и всё все необходимые данные полученны. Общение с API Твиттера будет расмотренно в следующей статье. Вывод строк со значениями сделаны для улучшения наглядности процесса авторизации и его понимания. Строки с дефисами вставлены для того, что бы выводимый текст не сливался в глазах в одну сплошную строку.

UPD: автор таки получил инвайт на хабр своими силами. Приветствуем shpaker!
+39
2 сентября 2010, 16:34
89
hobbeat 6,9

комментарии (16)

0
asmaster #
Большое спасибо! Как раз собирался использовать Twitter OAuth. Выслал инвайт.
+1
extragen #
Есть готовая библиотека для работы с твиттером — TweetSharp tweetsharp.codeplex.com/. Работает на многих платформах, хотя для windows phone 7 надо ее немного подфиксать.

А для oauth авторизации мне больше нравиться dotnetopenauth www.dotnetopenauth.net/
0
hobbeat #
Жаль, но про инвайт — обман. Или всё же три года подождать?
+1
Alex217Vish #
Есть такой проект — Twitterizer. Всё сделано вполне прилично и вполне себе работает.
Зачем изобретать велосипед?
0
mastak #
Я тоже использую в своих проектах Twitterizer.NET. Удобная штука.
0
gahcep #
Статья очень кстати. Только начал разбираться с публикацией в Twitter микросообщений-тревог (как в SCADA системах SMS-сообщения). Вот только спецификацию бегло пробежал и упустил тот факт, что нужен ввод нескольких параметров от пользователя, а графического вывода не имею :(
0
avenu #
В Твиттере, да и в самом OAuth рекомендуют использовать для передачи авторизационных данных не параметры, а заголовок Authorization. Впрочем, он часто бывает закрыт, например в браузерных приложениях.
0
khaale #
Оберните (HttpWebResponse)Request.GetResponse(); и new StreamReader(Response.GetResponseStream(), Encoding.GetEncoding(1251)); в using, или просто освободите ресурсы.
0
mezastel #
Положите в блог .Net
+1
hobbeat #
Тут дело не в том что лучше, что хуже. Смысл был разобраться с авторизацией и написать кусок кода который б не зависел от сторонних либ и был бы максимально прост.
Кстати писалось в Монодевелопе
PS: А писать свой код или использовать чужие наработки дело каждого
0
DbM #
Дайте предположу почему вышла эта статья) Сам весь день вчера подкручивал проект (правда на php) который перестал работать 01.09 — как только наш любимый твитер отключил поддержку basic auth. А за статью спасибо — как раз скоро будем делать проект под твиттер на .net
0
xeon #
Используйте TweetSharp tweetsharp.com/ — очень стабильная библиотека. Я его уже больше года на боевом проекте гоняю. Всем доволен.
+2
xeon #
Хорошая статья. Я предпочитаю TweetSharp и там это делается еще проще. Хотя и пример на сайте через Fluent-интерфейс нерабочий :)

И очень забавно смотреть, как все кинулись чинить после того, как всё упало.
Хотя twitter сначала просто рекомендовал OAuth, потом назначил дату апокалипса — 30 июня. Потом перенесли на 16 августа с постепенным урезанием API Rate limit.
И все все равно проспали. Вообще рекомендую твиттер-разработчикам подписаться на твиттер разработчиков API twitter.com/twitterapi
Станет меньше таких недоразумений :)

P.S. Сам спал до начала августа, потом срочно программу обновлял :)
+1
d_a #
Замечательная статья о том, как написать обертку для уже готового блока OAuth.

Строка Encoding.GetEncoding(1251) убила в самое сердце. Спасибо, что не КОИ-8, а то бы и комментарий написать не смог.
0
centur #
Встречный вопрос — а твиттер при запросе отдает email пользователя или только User_id?
0
shpaker #
На этапах описанных в этом посте только юзер_ид

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.