Авторизация в Яндексе – php, curl и cookies
Опубликовано 3 мая, 2009 в PHPВ прошлом посте мы делали POST запросы, а сегодня мы будем авторизироваться в Яндексе. Помимо отправки POST формы с логином и паролем, нам необходимо будет также авторизироваться, тоесть сохранить нужные куки и отдавать их в последующих запросах.
Поставим себе следующую задачу – получать содержимое панели вебмастера с помощью PHP.
Все знают, как при помощи PHP получить содержание той или иной страницы. Но в нашей задаче есть одна загвоздка – чтобы получить страницу с сайтами определенного аккаунта, нам нужно войти под этим аккаунтом. Для этого необходимо отправить POST форму отсюда. Внимательно изучаем все поля этой формы, нам необходимо отправить Яндексу все эти поля. В ответ Яндекс даст нам куку, которую мы должны сохранить и отдавать обратно Яндексу при каждом следующем посещении страницы с инфой, доступной только авторизированным пользователям.
Вот, собственно, функция авторизации:
<?php
$url = "http://passport.yandex.ru/passport?mode=auth"; //УРЛ, куда отправлять данные
/*
Переменные, которые мы будет отправлять Яндексу в виде POST запроса:
*/
$login = 'test'; //Логин
$passwd = 'test'; //Пароль
$user_cookie_file = $_SERVER['DOCUMENT_ROOT'].'/cookies.txt'; //Полный путь до файла, где будем хранить куки
$idkey = '3121235564020nVDfxvth2'; //Хрен знает что
$retpath = 'http://webmaster.yandex.ru/'; //Откуда мы пришли на страницу авторизации
$timestamp = ''; //Хрен знает что
$twoweeks = 'yes'; //Две недели какие-то
$In = 'Войти'; //Кнопка входа
/*
Функция:
*/
function auth($url) {
global $user_cookie_file, $idkey, $retpath, $timestamp, $login, $passwd, $twoweeks, $In; // Получаем все POST данные
/*
Небольшая прелюдия с инифиализацией cURL и прочей шулухой
*/
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)");
curl_setopt($ch, CURLOPT_COOKIEFILE, $user_cookie_file); //Куки раз
curl_setopt($ch, CURLOPT_COOKIEJAR, $user_cookie_file); //Куки два
curl_setopt($ch, CURLOPT_POST,1); //Будем отправлять POST запрос
/*
Формируем и отправляем тот самый POST запрос.
Как видите, это простая строка, мало чем отличающаяся от GET.
*/
curl_setopt($ch, CURLOPT_POSTFIELDS,"idkey=$idkey&retpath=$retpath×tamp=$timestamp&login=$login&passwd=$passwd&twoweeks=$twoweeks&In=$In");
$html = curl_exec($ch);
curl_close($ch);
return $html; //Возвращаем ответ Яндекса
}
auth($url); // Авторизируемся.
?>
С авторизацией все понятно – отправили логин, пароль и прочую информацию, сохранили отданные Яндексом куки. Теперь нам необходима функция, которая будет отдавать сохраненные куки Яндексу и получать ответ, тоесть ходить по защищенным страницам как добропорядочный живой юзер с настоящего добропорядочного браузера.
Вот эта функция:
<?php
function browser($url) {
$user_cookie_file = $_SERVER['DOCUMENT_ROOT'].'/cookies.txt'; //Получаем сохраненный после авторизации файл с куками.
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)");
curl_setopt($ch, CURLOPT_COOKIEFILE, $user_cookie_file); //Подставляем куки раз
curl_setopt($ch, CURLOPT_COOKIEJAR, $user_cookie_file); //Подставляем куки два
$html = curl_exec($ch);
curl_close($ch);
return $html; //Возвращаем ответ
}
echo browser('http://webmaster.yandex.ru/'); //Безпрепятственно выводим заветную инфу
?>
Надо также сказать, что авторизироваться достаточно один раз, а потом в течение 2х недель просто юзать функцию browser();
Думаю, вы понимаете, что описанным способом можно авторизироваться не только на Яндексе, а вообще где угодно.
Удачи.
Комментариев: 30. Обязательно оставьте свой!
Что-то у меня совсем не получилось авторизоваться
. Делал все в точности как в статье (логин с паролем ставил свои) а в ответ от функции browser – тишина. Если в ней еще установить параметр
то приходит ответ:
Если я правильно понимаю – авторизация в функции auth не проходит (хотя файлик cookies.txt формируется) и в функции browser яндекс опять перенаправляет на страницу авторизации
Разобрались где был касяк, в
curl_setopt($ch, CURLOPT_POSTFIELDS,»idkey=$idkey&retpath=$retpath×tamp=$timestamp&login=$login&passwd=$passwd&twoweeks=$twoweeks&In=$In»);
& нужно заменить на &
lis, спасибо, исправил.
Косяк редактора вордпресса в том, что со вставленным кодом в теге pre и вообще с html делает что захочет после публикации.
Ух ты ж блин, спасибо! полчаса уже с авторизацией парюсь, потом про гугл вспомнил
Чё-та нихрена это не работает….у меня даже cookies.txt не создаётся….первый раз юзаю curl….
бля помогите разобраться с этой фигнёй….уж очень нада
вроде разобрался….
Почему-то не работает… хотя подставляю все параметры правильно, странно…
Sharkmanru, необходимо дебажить – проверь, что возвращает Яндекс (какие заголовки), создается ли файл куков (права необходимо выставить, если не создается) и т.д. Пока сказать в чем проблема может быть невозможно.
Да я с консоли проверяю, всё верно, это точно…
Еще раз проверил, у меня работает, значит, Яндекс не менял ничего в способе и алгоритмах авторизации. Остается только дебажить, каждую переменную и каждое действие. Проблема должна лежать где-то на поверхности
скрипт не заходит, я его запускаю и никакого ответа нет, в чем дело может быть? куки не пишет вообще захожу пустая страница, с шела тоже!
insane, дебаж. Если файл куков не создается, возможно, прав нет. Посмотри, что возвращает Яндекс, само по себе auth($url) и не должно ни на что отвечать, замени на echo auth($url). Вывод ошибок включи.
Миллион причин может быть.
У меня тоже была проблема. Оказалось что лишний амперсанд (&) в строке параметров ставил.
Это:
curl_setopt ( $ср, CURLOPT_POSTFIELDS, ‘name=pablo&pass=1234&’);
Исправил на это:
curl_setopt ( $ср, CURLOPT_POSTFIELDS, ‘name=pablo&pass=1234′);
Надеюсь, что кому-нибудь поможет.
Сам 5 часов потратил на поиск ошибки.
Спасибо можно сказать тут: Z157719302428
А для гугля можете пример авторизации привести? А-то сижу вот чайник курла… там параметров километрище.. помогите плиз))
Вот, вроде выдернул:
Логин
Пасс
Помогите с составлением, пожалста
Orlenko K.N., в гугле все сложнее намного. На каком-то форуме наблюдал, как бились над этим, так и не добились ничерта. На досуге попробую авторизироваться.
Пробую вот по приведённому выше примеру сделать, FALSE выдаёт и всё тут
FALSE /accounts/ TRUE 0 GoogleAccountsLocale_session ru
Вот так вот..
Неповерите, но не работает!!!!!
Куки в файл пишет, а на запрос browser(ссылка) в ответ пустая страница приходит, такое ощющение что куки назад не отсылает, а может потому, что Locationв первом скрипте не выполнился….
Проверил у себя – работает. Значит – виной всему являются какие-то обстоятельства, нужно дебажить, найти это обстоятельство.
и еще –
echo browser(‘http://webmaster.yandex.ru/wmconsole/’);
сейчас там ничего нет, перенесли на:
echo browser(‘http://webmaster.yandex.ru/’);
Забираю свои слова обратно, все работает все ок!!!!
Причина оказалась echo browser(’http://webmaster.yandex.ru/’);
Спасибо АВТОРУ!!!!
Побольше бы таких статей и людей, которые пишут такие статьи в которых Разжовывают как и что работает, все с коментами, все супер!!!
Ещо раз спасибо АВТОРУ, очень помог!!!
Сайт в закладки обезательно…
Спасибо за статью, как раз искал то что надо, но поправьте в примере , а то пришлось комменты все читать, чтобы понять, почему лажа.
Спасибо. На основе реализовал простенький класс для пхп4 с 2мя функциями(для POST & GET запросов
), чтоб постоянно одинаковый код не вбивать и не искать:)
Кстати, рекомендую также добавить
curl_setopt($connect, CURLOPT_FOLLOWLOCATION, TRUE);
Ибо при логине на таких проектах, как мой мир, идет редирект между 4-5 страничками, и нам желательно их все обойти, а не встревать на 1ой.
На маил ру не получается зайти (ничего др. еще не пробывал.) еще при авторизации ответа никакого не возвращается, уки создаются нормально
вот содержимое куки (ящик скрыл ХХХХХХ)
# Netscape HTTP Cookie File
#
# This file was generated by libcurl! Edit at your own risk.
mail.ru FALSE / FALSE 0 PHPSESSID 05121a912d8d09c1fce140885fb7ce34
.mail.ru TRUE / FALSE 1272800713 Mpop 1265024713:06065e606a056b5b190502190f1d00071c06074f6a5d5e465e07030401031e0902011e4e4e4f464746404246145c555e551f4243:XXXXXXXXX@mail.ru:
.mail.ru TRUE / FALSE 1265197511 server 2
mail.ru FALSE / FALSE 0 uid 179799
вчем может быть проблема???
Во, лучше юзайте это, у меня все получилось
$cookie = $_SERVER['DOCUMENT_ROOT'].’/img/cookies.txt’;
$url = "http://g2.botva.mail.ru/login.php";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
curl_setopt($ch, CURLOPT_NOBODY, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
$result = curl_exec($ch);
curl_close($ch);
$url = "http://g2.botva.mail.ru/login.php";
$post = "login=*****&pass=******";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
curl_setopt($ch, CURLOPT_REFERER, "http://g2.botva.mail.ru/login.php");
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
curl_setopt($ch, CURLOPT_NOBODY, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
$result = curl_exec($ch);
curl_close($ch);
?>
Спасибо, доступно объяснено.
Интересно было бы посмотреть на использование куки с помощью сокетов
Если вы посниферите что шлет браузер во время авторизации на мыле яндекса, то заметите что post-зпароса там нет!
яша каким-то js скриптом формирует куки, записывает и шлет методом get на какой-то адрес, причем данные не передает в строке запроса. логин, base64 хеша и ещё что-то в куках передается на его сервер.
Возникла проблема с переносом скрипта, использующего cURL, на другую машину. Суть: на другой машине передаются не все полученные куки.
Кусок дебаг-лога с первой машины (curl –version
curl 7.20.0 (i686-pc-linux-gnu) libcurl/7.20.0 OpenSSL/0.9.8n zlib/1.2.4
Protocols: dict file ftp ftps http https imap imaps ldap ldaps pop3 pop3s rtsp smtp smtps telnet tftp
Features: Largefile NTLM SSL libz):
< HTTP/1.1 302 Found
< Date: Wed, 21 Apr 2010 13:32:40 GMT
< Server: Microsoft-IIS/6.0
< X-Powered-By: ASP.NET
< X-AspNet-Version: 2.0.50727
< Content-Encoding: gzip
< Location: /Reports/Transit.aspx
* Added cookie B2BUser="" for domain b2b.yyy.ru, path /, expire 1271770360
< Set-Cookie: B2BUser=; expires=Tue, 20-Apr-2010 13:32:40 GMT; path=/
* Added cookie 5AFDF04C-F06D-4049-8371-05121B247D87="CFFE909AC8073DCDC9A38856EBCA720C1C39F7E708E17E36646FDF225EE035250D0D54AAA9B67A08D987C22BC9A2C7B50421E58A4DFF76069E8788DD51399D58E52ADEB0337008A0AD04A9B2D85A221A" for domain b2b.yyy.ru, path /, expire 1271862760
< Set-Cookie: 5AFDF04C-F06D-4049-8371-05121B247D87=CFFE909AC8073DCDC9A38856EBCA720C1C39F7E708E17E36646FDF225EE035250D0D54AAA9B67A08D987C22BC9A2C7B50421E58A4DFF76069E8788DD51399D58E52ADEB0337008A0AD04A9B2D85A221A; expires=Wed, 21-Apr-2010 15:12:40 GMT; path=/; HttpOnly
< Cache-Control: private
< Content-Type: text/html; charset=utf-8
< Content-Length: 4082
<
* Ignoring the response-body
* Connection #0 to host b2b.yyy.ru left intact
* Issue another request to this URL: ‘https://b2b.yyy.ru/Reports/Transit.aspx’
* Violate RFC 2616/10.3.3 and switch from POST to GET
* Re-using existing connection! (#0) with host b2b.yyy.ru
* Connected to b2b.yyy.ru (xxx) port 443 (#0)
> GET /Reports/Transit.aspx HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)
Host: b2b.yyy.ru
Accept-Encoding: gzip
Referer:
Cookie: 5AFDF04C-F06D-4049-8371-05121B247D87=CFFE909AC8073DCDC9A38856EBCA720C1C39F7E708E17E36646FDF225EE035250D0D54AAA9B67A08D987C22BC9A2C7B50421E58A4DFF76069E8788DD51399D58E52ADEB0337008A0AD04A9B2D85A221A; B2BAccept=21.04.2010 17:32:38; ASP.NET_SessionId=qlcbxrmwoql1r5nfbiyudu55
Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg
Connection: Keep-Alive
Content-type: application/x-www-form-urlencoded
Со второй машины (curl –version
curl 7.18.2 (i486-pc-linux-gnu) libcurl/7.18.2 OpenSSL/0.9.8n zlib/1.2.3.3 libidn/1.8 libssh2/0.18
Protocols: tftp ftp telnet dict ldap ldaps http file https ftps scp sftp
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz):
< HTTP/1.1 302 Found
< Date: Wed, 21 Apr 2010 14:12:08 GMT
< Server: Microsoft-IIS/6.0
< X-Powered-By: ASP.NET
< X-AspNet-Version: 2.0.50727
< Content-Encoding: gzip
< Location: /Reports/Transit.aspx
* Added cookie B2BUser="" for domain b2b.yyy.ru, path /, expire 1271772728
< Set-Cookie: B2BUser=; expires=Tue, 20-Apr-2010 14:12:08 GMT; path=/
* Added cookie 5AFDF04C-F06D-4049-8371-05121B247D87="30FE90A67B8B88104DD13D3A051B9B28B11D9327C00BEBBAB14496056147D8EF39485022165247C52B49B4856958524AADD4385827F6A231C79E2DFCFB792240C96C329584F2A796FB3DBD871AF55C43" for domain b2b.yyy.ru, path /, expire 1271865128
< Set-Cookie: 5AFDF04C-F06D-4049-8371-05121B247D87=30FE90A67B8B88104DD13D3A051B9B28B11D9327C00BEBBAB14496056147D8EF39485022165247C52B49B4856958524AADD4385827F6A231C79E2DFCFB792240C96C329584F2A796FB3DBD871AF55C43; expires=Wed, 21-Apr-2010 15:52:08 GMT; path=/; HttpOnly
< Cache-Control: private
< Content-Type: text/html; charset=utf-8
< Content-Length: 4082
<
* Ignoring the response-body
* Connection #0 to host b2b.yyy.ru left intact
* Issue another request to this URL: ‘https://b2b.yyy.ru/Reports/Transit.aspx’
* Disables POST, goes with GET
* Re-using existing connection! (#0) with host b2b.yyy.ru
* Connected to b2b.yyy.ru (xxx) port 443 (#0)
> GET /Reports/Transit.aspx HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)
Host: b2b.yyy.ru
Accept-Encoding: gzip
Referer:
Cookie: B2BAccept=21.04.2010 18:12:07; ASP.NET_SessionId=fzkch2bm3c1noyinxdx4pnzr
Accept: image/gif, image/x-bitmap, image/jpeg, image/pjpeg
Connection: Keep-Alive
Content-type: application/x-www-form-urlencoded
На второй машине кука принимается, сохраняется в файл, но отправляется не вся. Очевидно, что есть различия в версиях курла, но может есть некая опция? Не хотельсь бы ковыряться в зависимостях дебиана…
Куку сохраняет, но авторизация не срабатывает. И есть мнение, что это из-за того, что мы не учитываем, возможно важные, параметры. Такие, как: $idkey, $timestamp.
$timestamp нужно записать так: $timestamp = time();
$idkey нужно, наверное сначала загрузить страничку и узнать значение поля idkey.
ох спасибо тебе, добрый человек.
лучей щастья!