Новости

Авторизація на сайті за допомогою curl php

Продовжуючи цикл статей присвячений парсером і всім, що з ними пов'язано. У цій статті розповім про те, як легко можна авторизуватися на будь-якому сайті за допомогою бібліотеку 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 =" & # тисячу сорок два; & # тисячі дев'яносто-три; & # 1110; & # +1076; " /> <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 трохи зручніше. Я звичайно не про браузер =)

Тепер авторізуемся на сайті, дивимося, що посилає форма при Сабміт.

Бачимо, що форма посилає такі параметри

login: login login: login: {loginmail} login: password: {password} login: j_id_id254.x: 8 login: j_id_id254.y: 7 javax.faces.ViewState: j_id1: j_id2

Спробуємо вирішити задачу в лоб і відправити ці дані простим масивом. Відразу врахуємо, що дані відправляються на захищений ssl url, по протоколу https. Це слід враховувати при відправці даних в cUrl. Розповідати, як працює SSL в рамках даної статті я не стану, скажу лише, що сертифікати, якими обмінюються дві сторони, самі по собі нічого не говорять про його володаря. Вони потрібні лише для того, щоб передати відкритий ключ, по обидва боки і служать для шифрування каналу зв'язку. Тобто ми можемо перевіряти наявність ssl, і підключати сертифікат в cUrl, але це буде служити користь тільки нам, сервер не може дізнатися користуємося ми сертифікатом, або використовуємо незахищений канал зв'язку.

// Про те, що ми авторизувалися будемо судити за наявністю форми logout function 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); // таймаут4 curl_setopt ($ ch, CURLOPT_SSL_VERIFYPEER, false); // просто відключаємо перевірку сертифіката curl_setopt ($ ch, CURLOPT_POST, 1); // використовувати дані в post curl_setopt ($ ch, CURLOPT_POSTFIELDS, array ( 'login' => 'login', 'login: login' => '[email protected]', '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);

... 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

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; }

Спробуємо висмикнути значення змінних полів

$ 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 скриптом. Спробуємо залишити їх як були

$ 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' => '[email protected]', '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.

Скрипт працює, але в більш складних випадках, доводиться емулювати виконання js скриптів, або просто з'ясовувати механізм їх роботи, щоб заповнити ті самі динамічно заповнюються поля. На жаль, цього не навчиш, все залежить від конкретного завдання і винахідливості програміста. За прикладами далеко ходити не треба, спробуйте для інтересу створити скрипт, який би відправляв автоматично, коментарі на xdan.ru. Бажаю удачі =)

Розповісти друзям

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

Или позвоните нам по телефонам: (048) 823-25-64

Организация (обязательно) *

Адрес доставки

Объем

Как с вами связаться:

Имя

Телефон (обязательно) *

Мобильный телефон

Ваш E-Mail

Дополнительная информация: