Несмотря на то, что движок WordPress имеет в своем составе XML-RPC, всё же иногда приходится прибегать к старым добрым методам авторизации через POST-запрос и парсить, парсить, парсить...Необходимость возникает, например, в случае, когда XML-RPC отключен в блоге.
Сегодня хотел было вернуться к Indy, но попробовав пару раз авторизоваться в своем блоге с использованием idHTTP, решил что гемморное это дело - использовать Indy. И буквально за 10 минут накидал небольшой примерчик авторизации в WordPress-блоге с использованием Synapse.
Для работы нам понадобиться всего один модуль 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://www.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://www.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+'&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))>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)>0 then label5.Caption:='Авторизовались' else label5.Caption:='Не авторизовались' end; end; end;
Теперь разберемся, что происходит в процедуре.
MimeType:='application/x-www-form-urlencoded'; d:=TStringStream.Create('log='+Edit1.Text+'&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))>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)>0 then label5.Caption:='Авторизовались' else label5.Caption:='Не авторизовались'
Которая и дает нам ответ на вопрос о том как прошла наша попытка авторизации.
Как видите весь код авторизации занял чуть больше 25 строк кода. Может я уже отвык от использования Indy, но по-моему авторизация с использованием Synapse оказалась намного проще.
Кстати, следует обратить внимание на то, что для дальнейшей работы с WordPress-блогом необходимо всегда передавать серверу Cookies, которые объект THTTPSend всегда автоматически сохраняет (и вставляет в запрос) в своем свойстве Cookies:TstringList.
На этом всё. Исходники рассмотренного выше пример можете скачать .
Вот уже и май на дворе. Скоро у школьников последний звонок, выпускной...и в Яндексе на первое место будет выходить запрос "фото выпускной" - надо же будет будущим менеджерам, программистам и просто большим боссам запечатлеть на фото своих школьных друзей и подруг. Так зачем терять время и искать в Интернете тех, кто сделает для вас замечательный фотоальбом на память? Обратитесь на fotozirka.com и не теряйте время на поиски фотографов ;)
------------------------
| Делись! | Загружай! | Плюсуй! |
| | |









02 мая 2010 в 10:01 дп
Indy
varpost: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('<a href="http://site.net/wp-login.php'" rel="nofollow">http://site.net/wp-login.php'</a>, post);
// Результат
if Pos('action=logout', result)>0 then
MessageDlg('Авторизация прошла успешно!', mtInformation, [mbOK],0)
else
MessageDlg('Авторизация Провалилась!', mtInformation, [mbOK],0);
except
post.Free;
end;
!!! Если пароль содержит символы ! » ? $ % ^ & ), то регистрация не проходит.
02 мая 2010 в 11:26 дп
Не пробовали в этом случае подключать модуль httpapp и заворачивать пароль в функцию HTTPEncode? Должно помочь
02 мая 2010 в 12:26 пп
Я в Делфи новичек. Спасибо, я попробую.
З.Ы. Блог отличный, много нужной информации. Буду заходить почаще :)
02 мая 2010 в 1:17 пп
Спасибо. Заходите, всегда рад новым читателям :)
13 Июн 2010 в 6:42 дп
Код приведенный тут у меня не работает :(
13 Июн 2010 в 7:16 дп
а конкретнее? На каком шаге не работает? У меня все работает, авторизуется
13 Июн 2010 в 7:36 дп
ошибок не дает. просто не авторизует
13 Июн 2010 в 6:30 пп
Есть проблема с кириллицей… не могу передать русские символы методом post
как быть?
13 Июн 2010 в 7:21 пп
делаю так:
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;
тут если RName — содержит кириллицу вообще ничего не записывает. Если только латинские символы (имеется ввиду если в тексте нет русских букв) записывает нормально.
как решить вопрос?
что я упустил?
14 Июн 2010 в 2:50 дп
вопрос снят
14 Июн 2010 в 9:09 дп
Доброго времени суток. Это снова я :)
Есть задача такого характера:
Необходимо создать новую запись в блоге…но надо сразу задать линк латиницей.
как это сделать?
synapse delphi 2009
14 Июн 2010 в 10:27 дп
Может вопрос мой непонятен. Тогда попробую пояснить.
Я synapse не юзал ранее…поэтому прошу подойти к вопросу снисходительно :)
Вопрос:
Собираюсь добавить новую запись через ../wp-admin/post-new.php
но тут только после вводе текста названия записи (заголовка) js формирует в div — innerhtml (надеюсь так понятнее). При этом он создает в линк последнюю часть как полное соответствие заголовка записи, а заголовок ессно на русском.
Требуется формировать линк латиницей. Как быть в данной ситуации?
+ как в synapse можно изменять значения объектов страницы (аналог document.GetElementById() или document.GetElementByTageName()) ? .. и вообще это можно сделать средствами synapse ?
Заранее благодарю за ответы
14 Июн 2010 в 12:30 пп
Никак. Synapse как и Indy, как и ICS и прочие библиотеки — это средства для работы с протоколом, а не DOM страницы. Для работы с элементами страницы используйте MSHTML и пр. библиотеки.
Раз вам нужно создавать новый пост в блоге, то огда может не стоит изобретать велосипед, а использовать XML-RPC вашего WordPress-блога?
26 Сен 2011 в 8:53 пп
Спасибо! Вы подали мне идею для брутера вп блогов)))