уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Несмотря на то, что движок WordPress имеет в своем составе XML-RPC, всё же иногда приходится прибегать к старым добрым методам авторизации через POST-запрос и парсить, парсить, парсить…Необходимость возникает, например, в случае, когда XML-RPC отключен в блоге.
Сегодня хотел было вернуться к Indy, но попробовав пару раз авторизоваться в своем блоге с использованием idHTTP, решил что геморное это дело — использовать Indy. И буквально за 10 минут накидал небольшой примерчик авторизации в WordPress-блоге с использованием Synapse.

Представленный в статье способ авторизации неактуален в связи с усложнением процесса автоматической авторизации в блоге на базе WordPress. Однако, вы можете использовать представленный ниже исходный код для того, чтобы разобраться с механизмами авторизации на других сайтах

Для работы нам понадобиться всего один модуль Synapse — httpsend.pas. Создадим новое приложение и подключим этот модуль в uses.
Теперь разместим на главной форме приложения следующие компоненты (см. рисунок):

в label5 будем выписывать результат авторизации («авторизовались» или «не авторизовались»), который будем определять самым простым способом — искать в загруженном документе подстроку «Log Out«, которая есть в админ.панели WordPress-блога:

Теперь, что касается технической стороны вопроса. Авторизация в блоге WordPress происходит следующим образом:
1. На странице блога http://blog.com/wp-login.php пользователь заполняет поля «Login» и «Password» и жмет кнопку «Log In»
2. Если логин и пароль правильные, то пользователя перенаправляют на страницу http://blog.com/wp-admin/
Форма запроса на ввод логина и пароля выглядит следующим образом:

<form name="loginform" id="loginform" action="http://webdelphi.ru/wp-login.php" method="post">
	<p>
		<label>Username<br />
		<input type="text" name="log" id="user_login" class="input" value="" size="20" tabindex="10" /></label>
	</p>
	<p>
		<label>Password<br />
         	<input type="password" name="pwd" id="user_pass" class="input" value="" size="20" tabindex="20" /></label>
	</p>
	<p class="forgetmenot"><label><input name="rememberme" type="checkbox" id="rememberme" value="forever" tabindex="90" /> Remember Me</label></p>
	<p class="submit">
		<input type="submit" name="wp-submit" id="wp-submit" class="button-primary" value="Log In" tabindex="100" />
		<input type="hidden" name="redirect_to" value="http://webdelphi.ru/wp-admin/" />
		<input type="hidden" name="testcookie" value="1" />
	</p>
</form>

Соответственно параметры запроса у нас будут следующие:
log=логин
pwd=пароль
Можно было бы для полноты картины добавить параметры testcookie и redirect_to, но в целом они не играют для нас никакой роли, поэтому их можно не включать в запрос.
Теперь договоримся как буем осуществлять авторизацию с Synapse.
1. Отправляем POST-запрос
2. Проверяем заголовки на наличие «Location: »
3. Если заголовок с перенаправлением есть, то GET-запросом получаем содержимое страницы и проверяем результат авторизации. Сразу приведу листинг процедуры авторизации:

procedure TForm2.Button1Click(Sender: TObject);
var d: TStringStream;
     s:string;
begin
with THTTPSend.Create do
  begin
    MimeType:='application/x-www-form-urlencoded';
    d:=TStringStream.Create('log='+Edit1.Text+'&amp;pwd='+Edit2.Text);
    Document.LoadFromStream(d);
    if HTTPMethod('POST',Edit3.Text+'/wp-login.php') then
      begin
        d.Clear;
        for S in Headers do
          begin
            if pos('location: ',LowerCase(s))&gt;0 then
              begin
                if HTTPMethod('GET',copy(S,11,length(S)-10)) then
                  begin
                    Document.SaveToStream(d);
                    break;
                  end;
              end;
          end;
        if pos('Log Out',d.DataString)&gt;0 then
          label5.Caption:='Авторизовались'
        else
          label5.Caption:='Не авторизовались'
      end;
  end;
end;

Теперь разберемся, что происходит в процедуре.

    MimeType:='application/x-www-form-urlencoded';
    d:=TStringStream.Create('log='+Edit1.Text+'&amp;pwd='+Edit2.Text);
    Document.LoadFromStream(d);

Обязательно указываем MimeType тип контента ‘application/x-www-form-urlencoded’. Кстати, то же самое необходимо и при работе с Indy, только там значение записывается в idHTTP.Request.ContentType.
Затем формируем строку запроса и записываем её в тело нашего POST-запроса.

 if HTTPMethod('POST',Edit3.Text+'/wp-login.php') then
      begin
        [...]
      end;

Если POST-запрос успешно выполнен, то проверяем, что вернулось. В нашем случае мы должны проверить содержимое заголовков ответа сервера, что мы и делаем здесь:

for S in Headers do
   begin
     if pos('location: ',LowerCase(s))&gt;0 then
       begin
          if HTTPMethod('GET',copy(S,11,length(S)-10)) then
            begin
               Document.SaveToStream(d);
               break;
            end;
      end;
    end;

Ищем в заголовках Headers заголовок «Location: » и, если таковой находится, то выполняем GET-запрос на адрес перенаправления. После чего, для удобства поиска, сохраняем тело ответного сообщения в поток d:TstringStream. Ну, а дальше элементарнейшая проверка:

if pos('Log Out',d.DataString)&gt;0 then
   label5.Caption:='Авторизовались'
else
  label5.Caption:='Не авторизовались'

Которая и дает нам ответ на вопрос о том как прошла наша попытка авторизации.
Как видите весь код авторизации занял чуть больше 25 строк кода. Может я уже отвык от использования Indy, но по-моему авторизация с использованием Synapse оказалась намного проще.
Кстати, следует обратить внимание на то, что для дальнейшей работы с WordPress-блогом необходимо всегда передавать серверу Cookies, которые объект THTTPSend всегда автоматически сохраняет (и вставляет в запрос) в своем свойстве Cookies:TstringList.

0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
15 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
Санек
02/05/2010 10:01

Indy
[code]var
post:TStringList;
result:string;
begin
post:=TStringList.Create;
try
// Параметры
post.Add('log=admin');
post.Add('pwd=123456');
post.Add('rememberme=forever');
post.Add('wp-submit=Войти');
post.Add('redirect_to=http://site.net/wp-admin/');
post.Add('testcookie=1');
// Отправляем данные
result:=IdHTTP1.Post('http://site.net/wp-login.php', post);
// Результат
if Pos('action=logout', result)>0 then
MessageDlg('Авторизация прошла успешно!', mtInformation, [mbOK],0)
else
MessageDlg('Авторизация Провалилась!', mtInformation, [mbOK],0);
except
post.Free;
end;[/code]

!!! Если пароль содержит символы ! » ? $ % ^ & ), то регистрация не проходит.

Санек
02/05/2010 12:26

Я в Делфи новичек. Спасибо, я попробую.
З.Ы. Блог отличный, много нужной информации. Буду заходить почаще :)

Nurlan
Nurlan
13/06/2010 06:42

Код приведенный тут у меня не работает :(

Nurlan
Nurlan
13/06/2010 07:36

ошибок не дает. просто не авторизует

Nurlan
Nurlan
13/06/2010 18:30

Есть проблема с кириллицей… не могу передать русские символы методом post
как быть?

Nurlan
Nurlan
13/06/2010 19:21

делаю так:
[code]
with HTTPSend do
begin
MimeType := 'application/x-www-form-urlencoded';
D := TStringStream.Create();
D.WriteString('cat_name=' + RName);
Document.LoadFromStream(D);
if HTTPMethod('POST', Edit1.Text + '/wp-admin/categories.php') then
begin
...
end;
end;
[/code]

тут если RName — содержит кириллицу вообще ничего не записывает. Если только латинские символы (имеется ввиду если в тексте нет русских букв) записывает нормально.
как решить вопрос?
что я упустил?

Nurlan
Nurlan
14/06/2010 02:50

вопрос снят

Nurlan
Nurlan
14/06/2010 09:09

Доброго времени суток. Это снова я :)
Есть задача такого характера:
Необходимо создать новую запись в блоге…но надо сразу задать линк латиницей.
как это сделать?

synapse delphi 2009

Nurlan
Nurlan
14/06/2010 10:27

Может вопрос мой непонятен. Тогда попробую пояснить.

Я synapse не юзал ранее…поэтому прошу подойти к вопросу снисходительно :)
Вопрос:
Собираюсь добавить новую запись через ../wp-admin/post-new.php
но тут только после вводе текста названия записи (заголовка) js формирует в div — innerhtml (надеюсь так понятнее). При этом он создает в линк последнюю часть как полное соответствие заголовка записи, а заголовок ессно на русском.
Требуется формировать линк латиницей. Как быть в данной ситуации?

+ как в synapse можно изменять значения объектов страницы (аналог document.GetElementById() или document.GetElementByTageName()) ? .. и вообще это можно сделать средствами synapse ?

Заранее благодарю за ответы

Анатолий
26/09/2011 20:53

Спасибо! Вы подали мне идею для брутера вп блогов)))

Виктор
Виктор
23/05/2014 20:36

Здравствуйте. У меня в итоге пустой stringstream, а сниффер показывает, что сервер ответил и авторизация прошла успешно