Почему я могу войти через эту форму с помощью браузера, но не LWP? - PullRequest
1 голос
/ 07 апреля 2011

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

<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("%s\n", $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};

Ответы [ 4 ]

2 голосов
/ 08 апреля 2011

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

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

1 голос
/ 08 апреля 2011

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

0 голосов
/ 08 апреля 2011

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

Как указывает 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-запрос, который одновременно отправляет, и искать соответствующие различия. Для браузера вы можете использовать расширение, такое как FireHox LiveHTTPHeaders или плагины Tamper Data, или использовать что-то вроде 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 в вашем примере.)

0 голосов
/ 08 апреля 2011

Я бы также порекомендовал LiveHTTPHeaders для Firefox.Вы включаете его, затем отправляете свою форму, и она точно показывает, что было GET или POST'd на сайт, включая все заголовки, параметры и файлы cookie, а затем показывает все ответы с сервера, включая установленные файлы cookie, заголовки и перенаправления..

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

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

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

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

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

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

...