(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
CAD Import .NET Professional пользовательская
Raize Components 6
IBM Domino Messaging Server Processor Value Unit (PVU) License + SW Subscription & Support 12 Months
Oracle Database Standard Edition 2 Named User Plus License
EMS Data Export for PostgreSQL (Business) + 1 Year Maintenance
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Программирование в AutoCAD
СУБД Oracle "с нуля"
eManual - электронные книги и техническая документация
Новые материалы
Программирование на Visual Basic/Visual Studio и ASP/ASP.NET
Мастерская программиста
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100