Авторизация на сайте при помощи curl php
- Категория: Парсеры
- Просмотров: 66399
Продолжая цикл статей посвященный парсерам и всем, что с ними связано. В этой статье расскажу про то, как легко можно авторизоваться на любом сайте при помощи библиотеку cUrl php. Для примера я взял один Украинский портал, к которому я собственно и буду подбирать ключики. Для работы нам также понадобится библиотека simple_html_dom
Авторизацию будем проходить на сайте http://tender.me.gov.ua , не буду создавать лишних ссылок, чтобы не накрыть нашу лавочку.
Для начала зарегистрируйтесь на сайте, чтобы иметь тестовые логин-пароль для входа на сайт.
На сайте мы видим ничем не примечательную форму авторизации.

"Внутренности" у нее тоже ничем не примечательны
<form id="login" name="login" method="post" action="/EDZFrontOffice/menu/uk/;jsessionid=c4651e96f5c2b9afb08776cbd1a5" enctype="application/x-www-form-urlencoded"> <input type="hidden" name="login" value="login" /> <input id="login:login" type="text" name="login:login" class="login" maxlength="80" /> <input id="login:password" type="password" name="login:password" value="" maxlength="80" class="login" /> <input type="image" src="images/t_login_button.png;jsessionid=c4651e96f5c2b9afb08776cbd1a5" name="login:j_id_id254" alt="Вхід" /> <input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="j_id1:j_id2" autocomplete="off" /></form> |
Итак смотрим, что форма авторизации отправляет при аутентификации. Для этого возпользуемся Google Chrome, открываем в нем сайт, затем Инструменты->Инструменты разработчика. Далее переходим на вкладку Network. Для браузера Opera Меню->Страница->Средства Разработки->Open Opera DragOnFly и вкладка Сеть. Хоть я и фанат Оперы, но на мой взгляд продукт от компании Google немного удобнее. Я конечно не про браузер =)
Теперь авторизуемся на сайте, смотрим, что посылает форма при сабмите.

Видим, что форма посылает следующие параметры
1
2
3
4
5
6
| login:loginlogin:login:{loginmail}login:password:{password}login:j_id_id254.x:8login:j_id_id254.y:7javax.faces.ViewState:j_id1:j_id2 |
Попробуем решить задачу в лоб и отправить эти данные простым массивом. Сразу учтем, что данные отправляются на защищенный ssl url, по протоколу https. Это следует учитывать при отправке данных в cUrl. Рассказывать, как работает SSL в рамках данной статьи я не стану, скажу лишь, что сертификаты, которыми обмениваются две стороны, сами по себе ничего не говорят о его обладателе. Они нужны лишь для того, чтобы передать открытый ключ, обеих сторон и служат для шифрования канала связи. Т.е. мы можем проверять наличие ssl, и подключать сертификат в cUrl, но это будет служить пользу только нам, сервер не может узнать пользуемся ли мы сертификатом, или используем незащищенный канал связи.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| //О том, что мы авторизовались будем судить по наличию формы logoutfunction isAuth( $data ){ return preg_match('#<form[^>]+id="logout"#Usi',$data);}$ch = curl_init();$url = 'https://tender.me.gov.ua/EDZFrontOffice/menu/uk/';curl_setopt($ch, CURLOPT_URL, $url ); // отправляем наcurl_setopt($ch, CURLOPT_HEADER, 0); // пустые заголовкиcurl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // возвратить то что вернул серверcurl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // следовать за редиректамиcurl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);// таймаут4curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// просто отключаем проверку сертификатаcurl_setopt($ch, CURLOPT_POST, 1); // использовать данные в postcurl_setopt($ch, CURLOPT_POSTFIELDS, array( 'login'=>'login', 'login:login'=>'mylogin@sitename.ru', 'login:password'=>'password', 'login:j_id_id254.x'=>8, 'login:j_id_id254.y'=>7, 'javax.faces.ViewState'=>'j_id1:j_id2',));echo isAuth($data = curl_exec($ch))?'Success':'Failed';curl_close($ch); |
Запускаем и видим, что ничего не получилось. Сайт просто так не сдался. Мы не учли одну вещь, данные об авторизации должны быть сохранены в cookie. Для этого добавим две строчки в код, к примеру после curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
1
2
3
4
5
| ...curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__).'/cookie.txt'); // сохранять куки в файлcurl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__).'/cookie.txt');... |
И снова мимо. Обратим внимание, что форма помимо стандартных логина-пароля, отправляет еще 3 динамических поля. Данные в них все время разные и генерируются при обновлении страницы. Значит, нужно загрузить страницу, скопировать эти данные и проходить аутентификацию уже с ними. Для этого немного "облагородим" код, заключив запрос данных с сервера cUrl'ом в отдельную функцию. Все отличие get запроса от post, заключается в том, что при пост запросе отправляются данные CURLOPT_POSTFIELDS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| function request($url,$post = 0){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url ); // отправляем на curl_setopt($ch, CURLOPT_HEADER, 0); // пустые заголовки curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // возвратить то что вернул сервер curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // следовать за редиректами curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);// таймаут4 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__).'/cookie.txt'); // сохранять куки в файл curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__).'/cookie.txt'); curl_setopt($ch, CURLOPT_POST, $post!==0 ); // использовать данные в post if($post) curl_setopt($ch, CURLOPT_POSTFIELDS, $post); $data = curl_exec($ch); curl_close($ch); return $data;} |
Попытаемся выдернуть значения переменных полей
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| $data = request('https://tender.me.gov.ua/EDZFrontOffice/');include 'simple_html_dom.php';$data = str_get_html($data);$auth = array( 'login'=>'login', 'login:login'=>'***************', 'login:password'=>'************l', 'login:j_id_id254.x'=>$data->find('input[name="login:j_id_id254.x"]',0)->value, 'login:j_id_id254.y'=>$data->find('input[name="login:j_id_id254.y"]',0)->value, 'javax.faces.ViewState'=>$data->find('input[name="javax.faces.ViewState"]',0)->value,);$data->clear();unset($data);print_r($auth); |
Оказывается, что поле login:j_id_id254.x и поле login:j_id_id254.y создаются и заполняются js скриптом. Попробуем оставить их как были
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| $url = 'https://tender.me.gov.ua/EDZFrontOffice/menu/uk/';$data = request('https://tender.me.gov.ua/EDZFrontOffice/');include 'simple_html_dom.php';$data = str_get_html($data);$auth = array( 'login'=>'login', 'login:login'=>'site@sitename.ru', 'login:password'=>'password', 'login:j_id_id254.x'=>10, 'login:j_id_id254.y'=>11, 'javax.faces.ViewState'=>$data->find('input[name="javax.faces.ViewState"]',0)->value,);$data->clear();unset($data);echo isAuth(request($url,$auth))?'Success':'Failed';; |
Вот и все, сайт побежден. Далее работаем с ним, как с обычным сайтом. Данные о том, что Ваш скрипт никто иной, как авторизованный пользователь бережно хранятся в cookie.
Комментариев нет:
Отправить комментарий