Русские документы
Ежедневные компьютерные новости RSS rusdoc.ru  Найти :
Новости
Последние поступления
Книжный магазин
  Hardware:
Видеоустройства
Системные платы
Процессоры
Мобильные устройства
Аудиосистема
Охлаждение системы
Накопители информации
КПК и ноутбуки
Телефоны и связь
Периферия
Система
Сети
Разные устройства
 
  Programming:
Web-разработка
Языки программирования
Технологии и теория
Разработка игр
Программная инженерия
 
  Software:
Операционные системы
Windows 7
Базы данных
Обзоры программ
Графика и дизайн
   
  Life:
Компьютерная жизнь
Разные материалы
   
Партнеры
Публикация
Правовая информация
Реклама на сайте
Обратная связь
Экспорт в RSS Экспорт в RSS2.0
    Читать в Яндекс.Ленте



Еще раз про авторизацию на сервере livejournal.com

Раздел: Programming / .NET Framework @ 11.11.2007 | Ключевые слова: ЖЖ программирование dotnet версия для печати

Автор: Ильин Евгений
Источник: jenyay.net

Введение

Эта статья является продолжением статьи Основы работы с сервером livejournal, в которой мы рассмотрели несколько видов авторизаций, которые могут быть использованы для написания клиента наподобие Semagic или LJ.NET. В этой статье мы с вами рассмотрим еще один способ авторизации на сайте livejournal.com (ЖЖ).

Рассмотренные ранее виды авторизации позволяют сделать только те операции, которые описаны в документации. Таким образом мы не сможем, например, получить доступ к подзамочным записям друзей, посколько для доступа к чужим записям (пусть даже только для чтения) нет соответствующей функции сервера по протоколу Flat или XML-RPC (по крайней мере их нет в документации). Эта статья как раз и описывает способ прочитать такие записи.

Авторизация

Если попытаться получить доступ к подзамочным записям, используя cookies, которые были получены при авторизации одним из способов, описанных в предыдущей статье, то у нас ничего не получится. Эти Cookies не дают нам прав на просмотр сообщений только для друзей. Таким образом получается, что должен быть еще какой-то способ авторизации.

Эмуляция отправки данных с формы

Давайте рассмотрим страницу авторизации на сайте ЖЖ, расположенную по адресу http://www.livejournal.com/login.bml. Если вы уже авторизованы на этом сайте в своем браузере, то нажмите кнопку "Выход" в правом верхнем углу. Итак, на этой странице неавторизованные пользователя видят две формы для входа в систему - в правом верхнем углу и слева в центре. Как ни странно, эти две формы работают по-разному. В данной статье мы рассмотрим авторизацию с помощью эмуляции отправки данных с нижней формы.

Если проследить с помощью какого-нибудь прокси-сервера, который может показывать передаваемые данные (я предпочитаю Proxomitron), что происходит при отправке данных с помощью этой формы, то мы увидим, что на сервер передаются следующие параметры:

chal Оклик (Challenge) сервера
response Сформированный с помощью пароля ответ
user Имя пользователя
password Пароль. Значение этого параметра остается пустым
lj_form_auth Идентификатор формы
action:login Значением этого параметра является просто надпись на кнопке для отправки данных с формы

Для авторизации требуются только первые три параметра. Параметр chal можно получить двумя способами. Можно загрузить страницу http://www.livejournal.com/login.bml и из полученного кода HTML выделить значение скрытого поля chal формы. В исходнике страницы этот параметр прописан следующим образом:

 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, который принимает три параметра: адрес загружаемой страницы, логин (имя пользователя) и пароль:

publicstring 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 используется довольно простая функция:

privatestring 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. Интересно, сколько еще разных методов авторизации таит в себе ЖЖ? :)

Это интересно:








версия для печатиРаспечатать статью


Вернуться в раздел: Programming / .NET Framework


Реклама:
Читать наc на:

Add to Google
Читать в Яндекс.Ленте






Rambler's Top100
© Copyright 1998-2012 Александр Томов. All rights reserved.