Некоторое время назад (можно даже сказать, что давно) передо мной встала задача сделать скрипт, который будет самостоятельно логиниться на один сайт через форму логина.
Форма выглядела примерно следующим образом:
- <form action="login.php" method="post">
- <input name="name" value="" type="text" />
- <input name="pwd" value="" type="password" />
- <input value="Войти" type="submit" />
- </form>
<form action="login.php" method="post"> <input name="name" value="" type="text" /> <input name="pwd" value="" type="password" /> <input value="Войти" type="submit" /> </form>
Первым делом я конечно проверил, а можно ли передать логин и пароль скрипту login.php методом GET. Т.е. залогиниться с помощью примерно следующего URL:
http://somesite.com/login.php?name=test&pwd=test
При условии конечно, что на сайте зарегистрирован пользователь с логином test и аналогичным паролем.
Попробовал я, и у меня не вышло. Исходника login.php я не видел, но тут можно запросто предположить, что login.php принимает логин/пароль через переменную $_POST, а не $_REQUEST (как частенько бывает). Получается, что метод GET у нас отпадает.
И я начал искать решение. Получилось, что мне нужно как-то передать форму, но без кода HTML, т.е. из кода PHP. Нашел решение в библиотеке CURL, что идет вместе с PHP в качестве расширения. А потом узнал про то, что можно обойтись и без CURL, используя обыкновенные сокеты. Об этих двух способах передачи данных серверу через POST я и поведу речь далее.
Передаем POST-данные с помощью CURL
Напишем функцию, которая запостит то, что мы ей скажем, и вернет содержимое страницы в случае успеха или FALSE в случае возникновения какой-то ошибки.
- // $url is string
- // $post is array
- // $ssl is boolean
- // $headers is array
- // $uagent is string
- // example: $post = Array('name1' => 'value1', 'name2' => 'value2')
- // returns:
- // $result is string/boolean
- function make_http_post_request($url, $post, $ssl = false, $headers = '', $uagent = '') {
- if (empty($url)) {
- return false;
- }
- $_post = Array();
- if (is_array($post)) {
- foreach ($post as $name => $value) {
- $_post[] = $name.'='.urlencode($value);
- }
- }
- $ch = curl_init($url);
- if ($ssl) { // если соединяемся с https
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
- }
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($ch, CURLOPT_POST, 1);
- curl_setopt($ch, CURLOPT_HEADER, 0);
- curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
- if (is_array($post)) {
- curl_setopt($ch, CURLOPT_POSTFIELDS, join('&', $_post));
- }
- if (is_array($headers)) { // если заданы какие-то заголовки для браузера
- curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
- }
- if (!empty($uagent)) { // если задан UserAgent
- curl_setopt($ch, CURLOPT_USERAGENT, $uagent);
- }
- $result = curl_exec($ch);
- if (curl_errno($ch) != 0 && empty($result)) {
- $result = false;
- }
- curl_close($ch);
- return $result;
- }
// $url is string // $post is array // $ssl is boolean // $headers is array // $uagent is string // example: $post = Array('name1' => 'value1', 'name2' => 'value2') // returns: // $result is string/boolean function make_http_post_request($url, $post, $ssl = false, $headers = '', $uagent = '') { if (empty($url)) { return false; } $_post = Array(); if (is_array($post)) { foreach ($post as $name => $value) { $_post[] = $name.'='.urlencode($value); } } $ch = curl_init($url); if ($ssl) { // если соединяемся с https curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); } curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); if (is_array($post)) { curl_setopt($ch, CURLOPT_POSTFIELDS, join('&', $_post)); } if (is_array($headers)) { // если заданы какие-то заголовки для браузера curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); } if (!empty($uagent)) { // если задан UserAgent curl_setopt($ch, CURLOPT_USERAGENT, $uagent); } $result = curl_exec($ch); if (curl_errno($ch) != 0 && empty($result)) { $result = false; } curl_close($ch); return $result; }
И, естественно, приведу пример ее использования:
- $post = Array('login' => 'test', 'pwd' => 'test');
- $headers = Array();
- $headers[] = "Content-type: application/x-www-form-urlencoded";
- $content = make_http_post_request('http://somesite.com/login.php', $post, false, $headers, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');
- if ($content !== false) {
- // анализируем контент
- } else {
- // какая-то ошибка
- }
$post = Array('login' => 'test', 'pwd' => 'test'); $headers = Array(); $headers[] = "Content-type: application/x-www-form-urlencoded"; $content = make_http_post_request('http://somesite.com/login.php', $post, false, $headers, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'); if ($content !== false) { // анализируем контент } else { // какая-то ошибка }
Передаем POST-данные с помощью сокетов
Если на хостинге есть CURL, то это просто отлично. А если нет? Тогда придется писать вышеприведенную функцию с использованием сокетов. Правда ее декларация будет немного отличаться (для простоты), но суть та же - передать данные удаленному скрипту методом POST:
- function make_http_post_request($server, $uri, $post, $uagent) {
- $_post = Array();
- if (is_array($post)) {
- foreach ($post as $name => $value) {
- $_post[] = $name.'='.urlencode($value);
- }
- }
- $post = implode('&', $_post);
- $fp = fsockopen($server, 80);
- if ($fp) {
- fputs($fp, "POST /$uri HTTP/1.1\r\nHost: $server \r\n".
- "User-Agent: $uagent \r\nContent-Type:".
- " application/x-www-form-urlencoded\r\n".
- "Content-Length: ".strlen($post)."\r\n".
- "Connection: close\r\n\r\n$post");
- $content = '';
- while (!feof($fp)) {
- $content .= fgets($fp);
- }
- fclose($fp);
- return $content;
- }
- return false;
- }
function make_http_post_request($server, $uri, $post, $uagent) { $_post = Array(); if (is_array($post)) { foreach ($post as $name => $value) { $_post[] = $name.'='.urlencode($value); } } $post = implode('&', $_post); $fp = fsockopen($server, 80); if ($fp) { fputs($fp, "POST /$uri HTTP/1.1\r\nHost: $server \r\n". "User-Agent: $uagent \r\nContent-Type:". " application/x-www-form-urlencoded\r\n". "Content-Length: ".strlen($post)."\r\n". "Connection: close\r\n\r\n$post"); $content = ''; while (!feof($fp)) { $content .= fgets($fp); } fclose($fp); return $content; } return false; }
Как видите, здесь мы соединяемся с заданным сервером с помощью fsockopen и посылаем post-данные, склеенные амперсандом. Преимущество функции, работающей через сокеты, состоит в том, что сокеты поддерживаются практически везде, в отличие от CURL. Сделать вторую функцию такую же, как и первую (т.е. сделать такую же декларацию/прототип), Вы можете самостоятельно (я уверен в этом ).
Единственное, что я еще хотел сказать, но не сказал про логин из скрипта - это то, что в форме логина должна отсутсвовать капча, иначе - Вам прямая дорога к изучению ее взлома и проведению собственных исследований
Постовой:
- Нужно охранять? Возьмите под видеонаблюдение свой объект. Системы от Пролайн.
- Witel-300 Data: радиоудлинитель телефонной линии позволяет передавать данные без потери качества на расстояния до 100 километров.
- Не обязательно сегодня должно быть 8 марта, чтобы подарить любимой женщине цветы. Вы можете заказать букет на сайте http://www.florio-fashion.com/
Популярность: 7%