|
СодержаниеВведениеЭта статья является продолжением статьи Основы работы с сервером livejournal, в которой мы рассмотрели несколько видов авторизаций, которые могут быть использованы для написания клиента наподобие Semagic или LJ.NET. В этой статье мы с вами рассмотрим еще один способ авторизации на сайте livejournal.com (ЖЖ). Рассмотренные ранее виды авторизации позволяют сделать только те операции, которые описаны в документации. Таким образом мы не сможем, например, получить доступ к подзамочным записям друзей, посколько для доступа к чужим записям (пусть даже только для чтения) нет соответствующей функции сервера по протоколу Flat или XML-RPC (по крайней мере их нет в документации). Эта статья как раз и описывает способ прочитать такие записи. АвторизацияЕсли попытаться получить доступ к подзамочным записям, используя cookies, которые были получены при авторизации одним из способов, описанных в предыдущей статье, то у нас ничего не получится. Эти Cookies не дают нам прав на просмотр сообщений только для друзей. Таким образом получается, что должен быть еще какой-то способ авторизации. Эмуляция отправки данных с формыДавайте рассмотрим страницу авторизации на сайте ЖЖ, расположенную по адресу http://www.livejournal.com/login.bml. Если вы уже авторизованы на этом сайте в своем браузере, то нажмите кнопку "Выход" в правом верхнем углу. Итак, на этой странице неавторизованные пользователя видят две формы для входа в систему - в правом верхнем углу и слева в центре. Как ни странно, эти две формы работают по-разному. В данной статье мы рассмотрим авторизацию с помощью эмуляции отправки данных с нижней формы. Если проследить с помощью какого-нибудь прокси-сервера, который может показывать передаваемые данные (я предпочитаю Proxomitron), что происходит при отправке данных с помощью этой формы, то мы увидим, что на сервер передаются следующие параметры:
Для авторизации требуются только первые три параметра. Параметр chal можно получить двумя способами. Можно загрузить страницу http://www.livejournal.com/login.bml и из полученного кода HTML выделить значение скрытого поля chal формы. В исходнике страницы этот параметр прописан следующим образом: <input type='hidden' name='chal' class='lj_login_chal' value='c0:1194717600:329:300:ji9Uky2mnUSi4UpL5G9z:350a128c3e91cf7543ee3aaacd45ee46' /> Но лучше, конечно, воспользоваться функцией getchallenge сервера с помощью протокола Flat или XML-RPC. Эту функцию мы уже использовали в предыдущей статье. Значение параметра response вычисляется точно так же, как и в методе авторизации Challenge/Response, рассмотренном ранее, а именно по формуле: MD5(chal + MD5(password)) Все эти данные надо отправлять по адресу http://www.livejournal.com/login.bml. Если все сформировано правильно, то в ответе сервера мы получим довольно много cookies. Из всех cookies для успешной загрузки подзамочных записей нам нужны будут только cookies с именами ljloggedin (таких cookies будет две штуки с одинаковыми значениями) и ljmastersession. Именно эти cookies и надо подцеплять к следующему запросу, который и будет читать записи только для друзей. Разумеется, если останутся и другие cookie, то ничего плохого не произойдет. Надо заметить, что при получении cookies в классе HttpWebRequest из .NET Framework необходимо установить значение параметра AllowAutoRedirect в false, иначе произойдет редирект на другую страницу и мы не сохраним cookies. Зато потом при использовании полученных cookies это значение должно быть true, так как при дальнейшей загрузке страницы с этими cookies происходит серия редиректов. Если AllowAutoRedirect будет равно false, то все эти редиректы придется отслеживать вручную. РеализацияДля демонстрации этого метода я дополнил проект LJServerTest из предыдущей статьи возможностью читать подзамочные записи. Скачать обновленные исходники можно здесь. При загрузке страницы с указанным адресом откроется новое окно, в котором будет показана загруженная страница с помощью контрола WebBrowser. Чтение подзамочных записей осуществляет метод GetPrivatePage() класса LJServer, который принимает три параметра: адрес загружаемой страницы, логин (имя пользователя) и пароль: public string GetPrivatePage (string url, string login, string password) { CookieCollection cookies = GetBaseCookie (login, password); string res = GetPage (url, cookies); return res; } Здесь мы сначала получаем cookies, выдаваемые при авторизации с помощью метода GetBaseCookie, а потом загружаем страницу, используя эти cookies. Получение cookies выглядит следующим образом: private CookieCollection GetBaseCookie (string login, string password) { // Получаем оклик сервера (см. предыдущую статью) string lj_login_chal = GetChallenge (); // Рассчитаем ответ как в методе авторизации challenge / response string auth_response = GetAuthResponse (password, lj_login_chal); // Строка запроса для отправки через форму string textRequest = string.Format ("chal={0}&response={1}&user={2}", HttpUtility.UrlEncode (lj_login_chal), HttpUtility.UrlEncode (auth_response), HttpUtility.UrlEncode (login)); byte[] byteArray = Encoding.UTF8.GetBytes (textRequest); // Получаем класс запроса HttpWebRequest request = (HttpWebRequest)WebRequest.Create ("http://www.livejournal.com/login.bml"); // Заполняем параметры запроса request.Method = "POST"; // Запрещаем автоматический редирект, чтобы сохранить cookies, полученные на первой странице после запроса request.AllowAutoRedirect = false; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = textRequest.Length; request.UserAgent = "LJServerTest"; // Очищаем коллекцию от старых cookie и добавляем туда новые request.CookieContainer = new CookieContainer (); // Заполняем параметры Proxy (_proxy == null, если прокси не используется) request.Proxy = _proxy; // Отправляем данные запроса Stream requestStream = request.GetRequestStream (); requestStream.Write (byteArray, 0, textRequest.Length); // Получаем класс ответа HttpWebResponse response = (HttpWebResponse)request.GetResponse (); // Читаем ответ Stream responseStream = response.GetResponseStream (); StreamReader readStream = new StreamReader (responseStream, Encoding.UTF8); string currResponse = readStream.ReadToEnd (); readStream.Close (); response.Close (); // Оставим только самые необходимые cookies CookieCollection newCollection = new CookieCollection (); for (int i = 0; i < response.Cookies.Count; i++) { if (response.Cookies[i].Name == "ljloggedin" || response.Cookies[i].Name == "ljmastersession") { newCollection.Add (response.Cookies[i]); } } return newCollection; } Обратите внимание, на строки кода, где формируется запрос. Не смотря на то, что при методе POST передаваемые параметры разделяются с помощью разделителя строк, здесь мы используем символ '&': "chal={0}&response={1}&user={2}". Запрос при этом будет сформирован как положено, но, если заменить амперсанды символами переводом строки, то авторизация не пройдет. В конце функции мы оставляем только cookies с именами ljloggedin и ljmastersession. Это сделано больше для демонстрации, чтобы показать, что и без других cookies все работает. В принципе, это делать не обязательно. А для загрузки страницы с использованием cookies используется довольно простая функция: private string GetPage (string url, CookieCollection cookies) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create (url); // Заполняем параметры запроса // Здесь мы разрешаем автоматические редиректы request.AllowAutoRedirect = true; request.Credentials = CredentialCache.DefaultCredentials; request.Method = "GET"; request.CookieContainer = new CookieContainer (); if (cookies != null) { request.CookieContainer.Add (cookies); } // Заполняем параметры Proxy (_proxy == null, если прокси не используется) request.Proxy = _proxy; // Получаем класс ответа HttpWebResponse response = (HttpWebResponse)request.GetResponse (); // Читаем ответ Stream responseStream = response.GetResponseStream (); StreamReader readStream = new StreamReader (responseStream, Encoding.UTF8); string currResponse = readStream.ReadToEnd (); readStream.Close (); response.Close (); return currResponse; } ЗаключениеНу вот мы и рассмотрели еще один способ авторизации на сайте livejournal.com. Интересно, сколько еще разных методов авторизации таит в себе ЖЖ? :) Ссылки
Пожалуйста, оцените материал
|