Подписка

добавить на Яндекс

Наши проекты

Delphi+Google

Google API

Google API в Delphi - проект с открытым исходным кодом.

Chrono

Chrono

Хронометр - программа для ведения списка задач.

ODFProc

ODFProc

ODFProc - работа с документами OpenOffice в Lazarus и FreePascal.

Поддержка блога

А тут я коплю на лицензию Delphi XE на iPad =).
Сумма пожертвования не фиксирована.

Публикации

Год назад

Случайный пост

Последние

Сообщения форума

Комментарии

Социальные сети

Google

Facebook

Twitter

Опрос

Вы сейчас или в ближайшем обозримом будущем планируете разрабатывать кроссплатформенное приложение с использованием Firemonkey?



Loading ... Loading ...

Блоги и сообщества

Статьи по Delphi DelphiFeeds.ru - Все Delphi-блоги Рунета Сообщество умных людей VR-Online.RU Бесплатный журнал для программистов и всех, кто интересуется IT Статьи и уроки по Delphi Новостной блог о высоких технологиях
Система Orphus
Опубликовал Vlad 1 мая 2010 в 18:36.
Категории: Delphi в Web.


Несмотря на то, что движок 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 и не теряйте время на поиски фотографов ;)
------------------------
Понравилась статья? Тогда:
Делись! Загружай! Плюсуй!
   Отправить PDF на   
Читай ещё статьи на WebDelphi.ru

Комментарии (14)

WP_Cloudy
  • Санек пишет:

    Indy

    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('<a href="http://site.net/wp-login.php&#039;" rel="nofollow">http://site.net/wp-login.php&#039;</a>, post);
    // Результат
    if Pos('action=logout', result)&gt;0 then
    MessageDlg('Авторизация прошла успешно!', mtInformation, [mbOK],0)
    else
    MessageDlg('Авторизация Провалилась!', mtInformation, [mbOK],0);
    except
    post.Free;
    end;

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

  • Vlad пишет:

    Не пробовали в этом случае подключать модуль httpapp и заворачивать пароль в функцию HTTPEncode? Должно помочь

  • Санек пишет:

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

  • Vlad пишет:

    Спасибо. Заходите, всегда рад новым читателям :)

  • Nurlan пишет:

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

  • Vlad пишет:

    а конкретнее? На каком шаге не работает? У меня все работает, авторизуется

  • Nurlan пишет:

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

  • Nurlan пишет:

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

  • Nurlan пишет:

    делаю так:


    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 — содержит кириллицу вообще ничего не записывает. Если только латинские символы (имеется ввиду если в тексте нет русских букв) записывает нормально.
    как решить вопрос?
    что я упустил?

  • Nurlan пишет:

    вопрос снят

  • Nurlan пишет:

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

    synapse delphi 2009

  • Nurlan пишет:

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

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

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

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

  • Vlad пишет:

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

    Никак. Synapse как и Indy, как и ICS и прочие библиотеки — это средства для работы с протоколом, а не DOM страницы. Для работы с элементами страницы используйте MSHTML и пр. библиотеки.

    Раз вам нужно создавать новый пост в блоге, то огда может не стоит изобретать велосипед, а использовать XML-RPC вашего WordPress-блога?

  • Анатолий пишет:

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

Ваш ответ

Внимание: Все комментарии модерируются, и это может вызвать задержку их публикации. Отправлять комментарий заново не требуется.

Пожалуйста, заключайте исходный код в тэги [code][/code].
Если код большой, то воспользуйтесь Вставкой кода на отдельной странице и оставьте в комментарии ссылку на исходник

   


перевозка офиса ,перевозка офиса киев , перевозка офиса по киеву --|--. Если vertu не видит сим карту, ремонт vertu доверьте профессионалам.