(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Аутентификация при использовании WebRequest и WebResponse (исходники)

Dimon aka Manowar

Все наверное уже знают как получить содержимое URL с помошью методов GET или POST используя классы WebRequest/WebResponse. Но бывают моменты, когда этого мало, например, когда для доступа к так желаемым данным необходимо пройти предварительно аутентификацию.

Вот и я столкнулся с подобной задачей. Нужно было программно обработать порядка тысячи страниц и получить из них некоторые значения. Но для получения этих страниц необходимо было пройти аутентификацию.

Поиски решения данной задачи в инете ни к чему не привели и пришлось в итоге заняться этим вплотную самому. Некоторое время было потрачено на исследования и тестирование и результат не заставил себя долго ждать.

Итак для начала теоретические выкладки. Обычно аутентификация пользователя на сайте происходит следующим образом:

  1. Пользователь вводит свои данные и отсылает форму на сервер.
  2. Сервер проверяет есть ли пользователь с такими данными в базе и если все ок - возвращает в ответе какие-то куки (неважно какие, важно, что по ним потом проверяется, аутентифицирован ли пользователь).
  3. При запросе защищенной страницы сервер проверяет наличие нужных кук и если все ок - возвращает страницу.

Значит, судя по данному алгоритму все, что нужно добавить к стандартному методу получения страниц по URL - это добавить в него поддержку кук. Ну раз надо - значит надо :). Ниже представлен код, решающий данную задачу, с комментариями.

Для начала необходимо сходить на нужный сайт ручками и посмотреть в коде переменные, которые посылаются формой при логине. Допустим их 3 - login, pwd и action (всегда равный login). Теперь можно начинать программировать.

Вначале все выглядит как в известном примере получения данных по POST запросу - создается экземпляр класса WebRequest с нужным URL, устанавливаются свойства ContentType и Method, создается строка парамеров, которую необходимо будет отправить на данный URL и затем отсылается туда. Возвращаемый сервером результат принимается в экземпляр класса HttpWebResponse.

HttpWebResponse result = null;
HttpWebRequest req = (HttpWebRequest) HttpWebRequest.Create("(URL для авторизации)");
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";

byte[] SomeBytes = null;
string FormParams = "Login=(имя пользователя)&Password=(пароль)&action=login";
SomeBytes = Encoding.UTF8.GetBytes(FormParams);
req.ContentLength = SomeBytes.Length;
Stream newStream = req.GetRequestStream();
newStream.Write(SomeBytes, 0, SomeBytes.Length);
newStream.Close();
result = (HttpWebResponse) req.GetResponse();

Теперь начинается самое интересное. Возвращаемые сервером куки передаются в заголовке ответа сервера с именем Set-Cookie. И теперь их необходимо получить из этого заголовка, создать на их основе правильный экземпляр класса CookieContainer и использовать его в дальнейших запросах.

Конечно для начала неплохо бы и проверить удачно ли прошла авторизация.

string[] cookieVal = null;
if(result.Headers["Set-Cookie"] != null)
	cookieVal = result.Headers["Set-Cookie"].Split(new char[] {','});

Stream ReceiveStream = result.GetResponseStream();
Encoding encode = Encoding.GetEncoding("utf-8");
StreamReader sr = new StreamReader( ReceiveStream, encode );
string answer = sr.ReadToEnd();
sr.Close();
result.Close();

Будем считать что все в порядке и пара имя/пароль правильные (все таки в данной статье обсуждается несколько иная тема). Теперь необходимо создать правильный экземпляр CookieContainer.

Возвращаемая в заголовке «Set-Cookie» строка содержит в себе список кук, разделенных запятыми. Каждая же кука имеет следующий формат: «(имя куки)=(значение куки);path=(путь куки);domain=(домен куки);Expires=(дата, до которой кука хранится)». Основываясь на этих данных и создается контейнер с возвращенными куками.

CookieContainer cookie = new CookieContainer();
foreach(string cook in cookieVal)
{
	string[] cookie1 = cook.Split(new char[] {';'});
	if(cookie1.Length < 2)
		continue;
	cookie.Add(new Cookie(cookie1[0].Split(new char[] {'='})[0], cookie1[0].Split(new char[] {'='})[1], 
                cookie1[1].Split(new char[] {'='})[1], cookie1.Length > 2 ? cookie1[2].Split(new char[] {'='})[1] : ""));
}

Проверка на длину массива куки вставлена из-за того, что дата в возвращаемой в Set-Cookie строке представлена в полном формате и имеет символ «,» в своем составе. Соответственно может получиться так, что некоторые элементы массива cookieVal будут содержать часть даты. А так как нас не особо интересует Expires дата - мы просто отбрасываем данные строки.

Теперь есть все для получения защищенных страниц. Для присоединения CookieContainer к экземпляру класса WebRequest используется свойство CookieContainer данного класса. Ну а дальше все, как по теории:

HttpWebRequest req1 = (HttpWebRequest) HttpWebRequest.Create((URL защищенной страницы));
req1.UserAgent = "Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+NT+5.0)";
//Вот оно - важное дополнение.
req1.CookieContainer = cookie;
req1.Method = "GET";
HttpWebResponse result1 = (HttpWebResponse) req1.GetResponse();
Stream ReceiveStream1 = result1.GetResponseStream();
StreamReader sr = new StreamReader( ReceiveStream1, encode );
string html = sr.ReadToEnd();
result1.Close();

Дело сделано :).



 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 28.02.2007 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
ABBYY Lingvo x6 Европейская Домашняя версия, электронный ключ
JIRA Software Commercial (Cloud) Standard 10 Users
IBM Domino Enterprise Server Processor Value Unit (PVU) Annual SW Subscription & Support Renewal
IBM Rational Functional Tester Floating User License
IBM DOMINO ENTERPRISE CLIENT ACCESS LICENSE AUTHORIZED USER ANNUAL SW SUBSCRIPTION & SUPPORT RENEWAL
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
СУБД Oracle "с нуля"
Новые материалы
Программирование на Visual Basic/Visual Studio и ASP/ASP.NET
Delphi - проблемы и решения
Мастерская программиста
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100