Почему я могу войти в систему через эту форму с помощью браузера, но не LWP?

#html #perl #forms #post #lwp

#HTML #perl #формы #Публикация #lwp

Вопрос:

Я пытался войти на веб-сайт, который использует эту форму с тремя входными данными для аутентификации.

 <form action="/login.html" method="post">
<div class="loginlabel1 aright">ID / Email: </div>
<div class="bsearchfield">
<input type="text" name="profid" class="inputBx" size="15" value="" />
</div>
<div class="clear"></div>
<div class="loginlabel1 aright">Password: </div>
<div class="bsearchfield">
<input type="password" name="password" class="inputBx" size="15" value="" />
</div>
<div class="clear"></div>
<div class="loginbutton1">
<input name="login"type="image" src="images/logi.gif" align="right" border="0" />
</div>
</form>
  

Если я войду в систему через браузер, успешный вход перенаправит меня на http://www.example.com/myhome.html.

Но следующий скрипт не регистрирует меня и возвращает ту же login.html страницу. Я что-то пропустил? Я не получаю никакого сообщения об ошибке. Я успешно разместил сообщение?

 #!/usr/bin/perl -w
use LWP 5.64;
my $browser = LWP::UserAgent->new || die " Failed LWP USER AGENT : $!";
$ENV{HTTP_proxy} = "http://proxy:port";
$browser->env_proxy;
$browser->cookie_jar({});
my @Header    = (
                    'User-Agent'      => 'Mozilla/4.76 [en] (Win98; U)',
                    'Accept'          => 'image/gif, image/x-xbitmap, image/jpeg,image/pjpeg, image/png, */*',
                    'Accept-Charset'  => 'iso-8859-1,*,utf-8',
                    'Accept-Language' => 'en-US',
              );

push @{$browser->requests_redirectable}, 'POST';
$response = $browser->post(
    "http://www.example.com/login.html",
    [
        'profid'   => 'username',
        'password' => 'password'
    ],@Header
);

$response->is_success or die "Failed to post: ", $response->status_line;
print "Successfully posted username and password.n" if $response->is_fresh;

#printf("%s",$response->content);
printf("%sn", $response->status_line);
printf("%s",   $response->header("Accept-Ranges"));
printf("%s",   $response->header("Age"));
printf("%s",   $response->header("ETag"));
printf("%s",   $response->header("Location"));
printf("%s",   $response->header("Proxy-Authenticate"));
printf("%s",   $response->header("Retry-After"));
printf("%s",   $response->header("Server"));
printf("%s",   $response->header("Vary"));
printf("%s",   $response->header("WWW-Authenticate"));
delete $ENV{HTTP_PROXY};
  

Комментарии:

1. возможно, вы можете попытаться диагностировать проблему. Вы получаете код ответа на перенаправление, или 200 OK, или что-то еще?

2. No..It возвращает мне ту же страницу входа. Нет кода ошибки

3. каков ваш код ответа? нормально ли значение 200? каковы полные заголовки?

4. ДА.. В ответ я получаю 200 OK. И выводит только поле заголовка ответа — server = Apache

Ответ №1:

Ваша кнопка отправки представляет собой изображение. При нажатии на ввод типа image браузер отправляет координаты пикселей, на которые вы нажали, в CGI. В вашей форме браузер отправил бы login.x и login.y вместе с profid и password .

Кстати, Firebug — отличный инструмент для отладки CGI.

Ответ №2:

Иногда им требуются правильные заголовки accept-encoding и / или refererer. Я бы также попробовал заголовок user-agent, чтобы быть уверенным.

Комментарии:

1. 1 Это точный способ отладки такого рода проблем. Также помогает сравнение запросов с помощью сетевого анализатора, такого как Wireshark.

Ответ №3:

Я бы также рекомендовал LiveHTTPHeaders для Firefox. Вы включаете ее, затем отправляете свою форму, и она показывает именно то, что было ПОЛУЧЕНО или ОТПРАВЛЕНО на сайт, включая все заголовки, параметры и файлы cookie, а затем показывает все ответы с сервера, включая установленные файлы cookie, заголовки и перенаправления.

На странице может быть javascript, создающий дополнительные параметры, которые вы не видите, когда просто смотрите на форму, координаты изображения соответствуют приведенному выше PacoRG, или может потребоваться, чтобы вы сначала приняли файл cookie и отправили его вместе с логином.

LiveHTTPHeaders также позволяет изменять заголовки и «replay» — это позволяет изменять то, что отправляется на сервер (любые заголовки, файлы cookie, параметры и т.д.), Чтобы помочь определить, что на самом деле требуется серверу для входа в систему.

Кроме того, я считаю, что LWP по умолчанию автоматически следует за перенаправлениями, поэтому страница может действительно перенаправляться, а вы ее не видите (я полагаю, что функция «simple_request» не следует за redirs.)

В ответе LWP вы можете пройти назад через любые перенаправления следующим образом:

 my $prev_res = $res->previous();
while ( $prev_res ) {
    print $prev_res->status_line . "n";
    $prev_res = $prev_res->previous();
}
  

Надеюсь, это поможет!

Ответ №4:

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

Как указывает PacoRG, кнопка отправки представляет собой изображение; таким образом, при отправке нажатием этой кнопки в браузере будут представлены поля с именами «login.x» и «login.y», а также «login».

Хороший способ избежать подобных проблем — использовать, например, WWW::Mechanize, который выполняет большую часть работы за вас:

 my $mech = WWW::Mechanize->new;
$mech->get('http://www.example.com/login.html');
$mech-submit_form(
    with_fields => {
        profid => $username,
        password => $password,
    },
);
  

В приведенном выше примере будет запрошена страница входа, найдена соответствующая форма и отправлена.

Кроме того, как говорили другие, если запросы из вашего скрипта обрабатываются иначе, чем запросы из вашего браузера, лучший способ отладки — получить полный HTTP-запрос, который оба отправляют, и поискать соответствующие различия. Для браузера вы можете использовать расширение, подобное LiveHTTPHeaders в Firefox, или плагины для несанкционированного доступа к данным, или использовать что-то вроде Wireshark для захвата запроса по мере его отправки. Что касается скрипта, вы можете легко заставить его выводить отправляемый запрос.

Например, для скрипта, использующего LWP::UserAgent или WWW::Mechanize (который относится к подклассам LWP::UserAgent), вы можете добавить:

 $mech->add_handler("request_send", sub { shift->dump; return });
$mech->add_handler("response_done", sub { shift->dump; return });
  

При этом будет удален отправленный необработанный запрос вместе с необработанным ответом от сервера. (Измените $mech на любую переменную, в которой находится ваш объект LWP::UserAgent / WWW::Mechanize — $browser в вашем примере.)