Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.02.2009, 23:34   #1
Квэнди
Старожил
 
Аватар для Квэнди
 
Регистрация: 13.12.2006
Сообщений: 3,859
По умолчанию Общие принципы авторизации на удаленных сайтах.

Этой темой я открою цикл ответов и объяснений самых распространенных проблем, с которыми сталкиваются программисты Delphi при написании программ, которые должны взаимодействовать с удаленными WEB сайтами.
Итак, у нас стоит задача при работе своей программы авторизоваться на неком удаленном сайте. Для простейшего примера я взял портал mail.ru
Зарегистрировал там пользователя programmers с паролем 1234
Итак, сначала немного теории: Авторизация на любом сайте происходит путем заполнения формы и отправки её данных некому удаленному крипту методом POST. На самом деле после того как вы заполнили формы и нажали на кнопку, данные отправятся в виде простой строки, содержащей все параметры и их значения разделенные разделителем.
Все формы на страницах описываются тегом <form> имеющим достаточное кол-во параметров, приведу самые нужные для нас:
Параметр method
Значение параметра method не зависит от регистра. Различают два метода — GET и POST. Существуют и другие методы, но они пока мало используются.
GET
Этот метод является одним из самых распространенных и предназначен для получения требуемой информации и передачи данных в адресной строке. Пары «имя=значение» присоединяются в этом случае к адресу после вопросительного знака и разделяются между собой амперсандом (символ &). Удобство использования метода GET заключается в том, что адрес со всеми параметрами можно использовать неоднократно, сохранив его, например, в «Избранное» браузера, а также менять значения параметров прямо в адресной строке.
POST
Метод POST посылает на сервер данные в запросе браузера. Это позволяет отправлять большее количество данных, чем доступно методу GET, поскольку у него установлено ограничение в 4 Кб. Большие объемы данных используются в форумах, почтовых службах, заполнении базы данных и т.д.

Параметр Action
Указывает обработчик, к которому обращаются данные формы при их отправке на сервер. В качестве обработчика может выступать CGI-программа или HTML-документ, который включает в себя серверные сценарии (например, Parser). После выполнения обработчиком действий по работе с данными формы он возвращает новый HTML-документ.

Если параметр action отсутствует, текущая страница перезагружается, возвращая все элементы формы к их значениям по умолчанию.
(Описания параметров предоставлены сайтом htmlbook.ru)
Итак, заходим на сайт Mail.ru и смотрим исходный код страницы.
Ищем тег "<form" Разумеется, на странице может быть множество форм, но необходимая нам достаточно интуитивно понятно находится:
Цитата:
<form name="Auth" method="post" action="http://win.mail.ru/cgi-bin/auth">
Далее ищем закрывающий тег формы </form> и копируем себе в блокнот все содержимое формы для его тщательного рассмотрения.
Итак, вот мы получили форму:
Код:
<form name="Auth" method="post" action="http://win.mail.ru/cgi-bin/auth"> 
<img src="/mail/ru/images/log_bms.gif" width="226" height="18" usemap="#logbms" alt="" /><br />
<map name="logbms" id="logbmsid"><area shape="rect" coords="109,1,220,18" 
href="http://agent.mail.ru" alt="Агент"></area><area shape="default" nohref="nohref" alt=""></area></map><table class="authorization">
<tr>
<td colspan="2" class="registration">
<a href="http://win.mail.ru/cgi-bin/signup" class="left">Регистрация&nbsp;в&nbsp;почте</a>
<a
href="http://r.mail.ru/cln2840/www.mail.ru/pages/help/index.html"><img src="/mail/ru/images/helpm.gif"
width="14" height="14" alt="" class="right" /></a>
</td>
</tr>
<tr>
<td class="title1">Имя</td>
<td class="mail"><table><tr>
<td class="login"><input type="text" class="long" size="10" name="Login" tabindex="1" value="programmers" /><div>&nbsp;</div></td>
<td class="domain"><select size="1" name="Domain" class="long" tabindex="2">
<option value="mail.ru"
selected="selected">@mail.ru</option><option value="inbox.ru"
>@inbox.ru</option><option value="bk.ru"
>@bk.ru</option><option value="list.ru"
>@list.ru</option>
</select><div>&nbsp;</div></td>
</tr></table></td>
</tr>
<tr>
<td class="title2">Пароль</td>
<td class="pswd"><table><tr>
<td><input type="password" class="long" size="15" name="Password" tabindex="3"
value="" /></td>
<td class="forget"><div><a href="http://win.mail.ru/cgi-bin/passremind">Забыли?</a></div></td>
</tr></table></td>
</tr>
<tr>
<td class="title3"> </td>
<td class="button"><table><tr>
<td class="check"><input type="checkbox" id="alien" name="level" value="1" tabindex="4" class="check" /></td>
<td class="bad"><label for="alien">Чужой компьютер</label></td>
<td class="submit"><input type="submit" value="Войти" tabindex="5" class="submit" /></td>
</tr></table></td>
</tr>
</table>
</form>
Вложения
Тип файла: rar mailauth.rar (296.5 Кб, 1052 просмотров)
ICQ не для вопросов, а для предложений. Для вопросов используйте форум
IRC канал клуба программистов|Мои статьи

Последний раз редактировалось Квэнди; 24.03.2009 в 08:17.
Квэнди вне форума Ответить с цитированием
Старый 14.02.2009, 23:35   #2
Квэнди
Старожил
 
Аватар для Квэнди
 
Регистрация: 13.12.2006
Сообщений: 3,859
По умолчанию

На сервер могут отправится только значения элементов формы, которым относятся:
Тег input который отвечает за ввод информации и может принимать множество видов и вариантов. Вплоть до выбора файла, но об этом уже в следующих темах.
Внимание, ВСЕ теги Input лучше заполнять перед отправкой, поэтому обращайте внимание на теги Input с параметром type, имеющим тип type="hidden". Более конкретно о них я расскажу в конце.
Тег <select> отвечает за выбор элемента из фиксированного списка. Внутри тега <select> должны присутствовать теги <option> каждый из которых описывает один из параметров списка. Выбранный элемент списка отображается свойством selected тега option но для нас это малоинтересно, нам гораздо интересней параметр value тега option, который отражает именно тот текст, который будет отправлен на сервер при выборе этого элемента.
Ну вот собственно и все, теперь соберем всю необходимую нам информацию воедино:
Адрес, на который мы должны отправить запрос, чтобы авторизоваться мы берем из параметра action тега <form>
Метод отправки запроса выбираем из параметра method тега <form>
Код:
method="post"
Далее выбираем все необходимые нам поля:
Код:
<input type="text" class="long" size="10" name="Login" tabindex="1" value="" />
Код:
<select size="1" name="Domain" class="long" tabindex="2">
<option value="mail.ru"
selected="selected">@mail.ru</option><option value="inbox.ru"
>@inbox.ru</option><option value="bk.ru"
>@bk.ru</option><option value="list.ru"
>@list.ru</option>
</select>
Код:
<input type="password" class="long" size="15" name="Password" tabindex="3"
value="" />
Вот и все что нам понадобится.
Теперь перейдем к Delphi.
Создадим новый проект. "Бросим" на форму компонент IdHTTP из вкладки Indy Clients и кнопку.
теперь настроим наш компонент IdHTTP.
Поставим параметр AllowCookies в True (оговорюсь сразу: это на всякий случай, ибо далеко не всегда после авторизации и во время её задействованы cookies)
Выставим параметр HandleRedirects в True (вы можете и оставить этот параметр в False, но в этом случае рискуете после авторизации получить сообщение о просто успешном выполнении запроса, которое совершенно не говорит об успешности авторизации, либо о том, что был обнаружен redirect) Этот параметр позволяет IdHTTP в случае получения директивы http redirect следовать этому перенаправлению. Дело в том, что в большинстве случаев скрипты, которые авторизую пользователя, после авторизации перенаправляют его на некую страницу, поэтому нам гораздо интересней узнать именно её текст.
Собственно и все, больше никаких параметров нам не потребуется.
Теперь напишем обработчик нажатия на кнопку:
Код:
procedure TForm5.btn1Click(Sender: TObject);
var params,responseres:tstringlist;
begin
params:=TStringList.Create;
responseres:=TStringList.Create;
try
params.Add('Login=programmers');
params.Add('Domain=mail.ru');
params.Add('Password=1234');
responseres.Text:=http1.Post('http://win.mail.ru/cgi-bin/auth',params);
if Pos('logout',responseres.Text)>0 then
  ShowMessage('Авторизовались!');
finally
params.free;
responseres.free;
end;
end;
Разберем код:
сначала нам необходимо создать список параметров, которые мы будем передавать серверу для успешной авторизации. Выше мы уже выделили все необходимые поля, которые нам надо заполнить.
Создадим список:
Код:
params:=TStringList.Create;
и заполним его в соответствии со следующим правилом:
<параметр>=<значение>
Значение ни в какие кавычки заключать не надо.
Код:
params.Add('Login=programmers');
params.Add('Domain=mail.ru');
params.Add('Password=1234');
Обратит внимание, что мы присвоили параметру Domain значение mail.ru
так как именно этот текст стоял в значении параметра value нужного нам тега option:
Цитата:
<option value="mail.ru">@mail.ru</option>
Теперь отправим Post запрос (так как именно этот тип запроса используется в форме:
Цитата:
<form name="Auth" method="post"
) На адрес http://win.mail.ru/cgi-bin/auth так как именно он указан в качестве action формы:
Цитата:
<form name="Auth" method="post" action="http://win.mail.ru/cgi-bin/auth">
Результат выполнения нашего запроса мы сохраняем в свойстве text другого нашего списка строк. Итого в результате выполнения команды
Код:
responseres.Text:=http1.Post('http://win.mail.ru/cgi-bin/auth',params);
В переменной responseres мы получили весь исходный код страницы, которую нам вернул сервер после отправки формы. Для проверки корректности авторизации я воспользовался простым способом: на странице, которая отображается после авторизации присутствует кнопка выхода, которая именуется logout, вот её- то м и ищем в полученной нами странице. И, если она присутствует, то значит авторизация прошла успешно =)
ICQ не для вопросов, а для предложений. Для вопросов используйте форум
IRC канал клуба программистов|Мои статьи

Последний раз редактировалось Квэнди; 21.03.2009 в 00:31.
Квэнди вне форума Ответить с цитированием
Старый 21.03.2009, 00:31   #3
Квэнди
Старожил
 
Аватар для Квэнди
 
Регистрация: 13.12.2006
Сообщений: 3,859
По умолчанию

К сообщению я прикрепил описанный проект:http://programmersforum.ru/attachmen...5&d=1234643278
среда: Delphi 2009
Версия Indy: 10.2.5
ICQ не для вопросов, а для предложений. Для вопросов используйте форум
IRC канал клуба программистов|Мои статьи
Квэнди вне форума Ответить с цитированием
Старый 28.04.2009, 17:14   #4
Des
Форумчанин
 
Регистрация: 12.11.2008
Сообщений: 124
По умолчанию

Огромное спасибо, превосходная статья
Des вне форума Ответить с цитированием
Старый 25.05.2009, 10:40   #5
Hans
 
Регистрация: 25.05.2009
Сообщений: 4
По умолчанию

Огромное спасибо, изумительная статья, понятная даже для ламеров.
Но, не могли бы Вы еще помочь с TWebBrowser, как там отправлять postdata?
Заранее огромное спасибо, и я эту статью повешаю на стену, как вечную памятку.
Hans вне форума Ответить с цитированием
Старый 06.12.2009, 09:46   #6
AquaKlaster
Delphi,Python,PHP
Форумчанин
 
Аватар для AquaKlaster
 
Регистрация: 04.04.2009
Сообщений: 138
По умолчанию Еще немного примеров как авторизоватся на удаленных сайтах!

Пример авторизации на сайте с помощью idHTTP.Post

Несмотря на то, что все мои заготовки статей канули в Лету вместе с другими данными (в том числе исходниками), которые были на флешке, я не пала духом и попытаюсь написать что-нибудь полезное заново.

Сегодня расскажу, как использовать idHTTP.Post для авторизации на сайте. Я возьму для примера сайт LiveJournal.com.

Немного теории для начинающих. Итак, вызов метода Post компонента idHTTP отличается от вызова Get-а только тем, что помимо URL-а необходимо передать параметры. Параметры можно передавать в виде StringList-а, или каких-нибудь Stream-ов, или чего-нибудь еще подходящего.)

Пример Post-процедуры (параметры передаются в виде StringList-а):

Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  LoginInfo: TStringList;
  Response: TStringStream;
begin
  try
    LoginInfo := TStringList.Create;
    Response := TStringStream.Create('');
    LoginInfo.Add('username=MyName');
    LoginInfo.Add('password=MyPass');
    IdHTTP1.Post('http://mywebsite.xxx/login.php',LoginInfo,Response);
    Showmessage(Response.DataString);
  finally
    begin
      Response.Free;
      LoginInfo.Free;
    end;
  end;
end;


Пример Post-функции (параметры передаются в виде IdMultiPartFormDataStream-а):

Код:
uses IdMultipartFormData;
{ .... }

procedure TForm1.Button1Click(Sender: TObject);
var
  data: TIdMultiPartFormDataStream;
begin
  data := TIdMultiPartFormDataStream.Create;
  try
    // добавляем нужные параметры
    data.AddFormField('param1', 'value1');
    data.AddFormField('param2', 'value2');
    // для примера выводим в мемо все, что вернулось
    Memo1.Lines.Text := IdHTTP1.Post('http://localhost/script.php', data);
  finally
    data.Free;
  end;
end;


Сейчас попробуем применить полученные знания. Идем на LiveJournal.com, включаем сниффер, логинимся на сайте и смотрим, какие параметры надо передавать ('mode=login', 'user=логин', 'password=пароль'). Авторизация не произойдет, если на стороне клиента не будут сохранены кукисы. Для сохранения кукисов среди компонентов Indy существует TidCookieManager. IdCookieManager подключается к idHTTP через свойство CookieManager.

idHttp.CookieManager := IdCookieManager;


В этом случае при запросах в заголовок добавляются кукисы, автоматически сохраненные в IdCookieManager. IdCookieManager можно найти на закладке Indy Misc или создать динамически.

Поместим на форму 2 TEdit-а, TMemo и кнопку, на которую повесим следующий работающий код авторизации:

Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  Http  : TidHttp;
  CM    : TidCookieManager;
  Data  : TStringList;
  StrPage, UserID,  UserName  :  String;
  i : integer;
begin
  try
    Http := TIdHTTP.Create(Self);
    Data := TStringList.Create;
    CM := TidCookieManager.Create(Http);
    Http.AllowCookies := true;
    Http.CookieManager := CM;
    Http.HandleRedirects := true;

    Http.Request.Host:='livejournal.com';
    Http.Request.UserAgent:='Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10';
    Http.Request.Accept:='text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
    Http.Request.AcceptLanguage:='ru,en-us;q=0.7,en;q=0.3';
    Http.Request.AcceptCharSet:='windows-1251,utf-8;q=0.7,*;q=0.7';
    Http.Request.Referer:='http://www.livejournal.com/';

    Data.Add('mode=login');
    Data.Add('user=' + Edit1.Text);
    Data.Add('password=' + Edit2.Text);
    StrPage := Http.Post('http://www.livejournal.com/login.bml?ret=1', Data);
  finally
    Data.Free;
    CM.Free;
    Http.Free;
  end;

  if Pos('<input class="logoutlj_hidden" id="user" name="user" type="hidden" value="'+Edit1.Text,StrPage) <> 0 then
    ShowMessage('Авторизация прошла успешно')
  else
    ShowMessage('Авторизация провалилась');

  Memo1.Lines.Text := StrPage;
end;


Возвращенные заголовки (после ответа сервера) можно посмотреть так:
Код:
idHttp.Response.RawHeaders.GetText;


Сохраненные в CookieManager-е кукисы можно посмотреть так:

Код:
for i := 0 to Http.CookieManager.CookieCollection.Count - 1 do
  StrPage := StrPage + CM.CookieCollection.Items[i].CookieText + #13#10;


Вот что записал туда LiveJourmal.com:


Ну вот впринципе и всё, спасибо за внимание!
AquaKlaster вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Восстановление удаленных файлов Rio309 Компьютерное железо 9 17.11.2011 13:35
О сайтах shv-dr Софт 1 12.11.2008 09:53
Восстановление удаленных записей InterBase Vinas БД в Delphi 3 05.12.2007 10:29
Администрирование\управление компьютером\Общие папки\Общие ресурсы\прекратить общий доступ lm_strj Безопасность, Шифрование 2 13.10.2007 21:28