Блог → «Неверный логин или пароль Вконтакте» или небольшое исследование на тему изменений в процессе авторизации сайта Vkontakte
Доброго времени суток, уважаемые. Начиная с прошлой недели многие пользователи сторонних разработок на тему «а давайте использовать контент в Вконтакте без захода на сам сайт» могли лицезреть нечто подобное изображению из заголовка. Эта проблема меня никак не волновала, если бы не один «домашний» проектик, которому в админке нужна возможность свободного доступа к VK.
Авторизация ВКонтакте
Для начала, давайте поговорим о текущей схеме кроссдоменной авторизации на «Вконтактике». Так как VK, на данный момент, включает в себя 2 основных сайта (vk.com и vkontakte.ru), администрацией ресурса было принято решение организовать сквозную авторизацию на обоих ресурсах. Это значит, что авторизировавшись на вконтактике, вы свободно можете набрать vk.com и попасть на «англоязычный» вариант своего профиля. Особого смысла я в этом не вижу, т.к. большая часть хомячков слыхом не слыхивала о vk.com, но так уж оно есть и приходится с этим жить.
Как же «выглядит» процесс авторизации на сервисе через браузер?
- Пользователь запрашивает страницу
vkontakte.ruи получает во ответ почти обычную HTML страницу. Почему «почти», потому что в нее встроен то ли некий JS, то ли iframe (признаться честно не разбирался), который запрашивает уvk.comинформацию об этом пользователе. Судя по всему, если пользователь авторизирован наvk.comи по какой-то причине не прошел процедуру сквозной авторизации, эта авторизация будет проведена при первом входе на русскоязычную версию. - Далее пользователь вводит свои логин с паролем. Дорогой читатель, если ты думаешь, что данные сразу отправляют скрипту, ты глубоко заблуждаешься. Сначала отправляется AJAX запрос на
http://vkontakte.ru/login.phpс одним единственным параметромopзначение которогоa_login_attempt. Ответом всегда(!) служит строкаvklogin. Сакральный смысл сего действа до сих пор скрыт от меня. Возможно, где-то в зарослях JS кода скрыт набор вариантов серверов для логина иvkloginэто один из них. Возможно, это своеобразная защита от тупого копирования страницы с целью фишинга (хотя, не понимаю как это может защитить, кроме того, что кнопка будет неактивна и «хацкер» пойдет искать знающего знакомого). В любом случае это действо происходит всегда и лишь после него браузер начинает процесс собственно авторизации. -
http://login.vk.com/?act=login— пожалуй, самый знаменитый адрес для всех разработчиков, кто занимался выуживанием информации из недр контакта. Именно по этому адресу отправляются ваши логин с паролем. Именно от этого адреса зависит какая страница будет показана следующей.- Если введенные данные успешно проходят проверку, пользователю возвращается страница со скрытой формой, которая в автоматическом режиме будет отправлена на
http://vkontakte.ru/login.php?op=slogin. - Если же логин или пароль неправильны, будет возвращена пустая страница с кодом ответа 302 и заголовком
Location: http://vkontakte.ru/
- Если введенные данные успешно проходят проверку, пользователю возвращается страница со скрытой формой, которая в автоматическом режиме будет отправлена на
«Неверный логин или пароль». Why?
Давайте сравним заголовки запросов к серверу при отправке данных из Flash и браузера


Это запросы из браузера и флеша, соответственно. Я отметил спорные моменты по которым сервер Вконтакта может догадаться, что авторизация проводится не через браузер. Лично я в качестве причины предположил заголовок x-flash-version, как если бы контакт начал закрывать себя от «пиратов». Почему не Referer спросите вы, ну, просто потому что в моей реализации я сам контролирую все заголовки и Referer был заменен на нужный еще в первой версии программы. Ну, на всякий пожарный. Как выяснилось позже, проблема была не в этом.
Итак, главный подозреваемый - заголовок x-flash-version. Гуглу не удалось ответить на главный вопрос — как убрать этот заголовок. Да, вы можете заменить его значение на пустое, но полностью избавиться от него не представляется возможным. Что самое интересное, месяцев пять-шесть назад, когда я разрабатывал первую версию кода для авторизации во ВКонтакте из AIR приложения, этого заголовка не было. Удивительно.
После впустую убитых полутора часов, мне в голову пришла гениальнейшая мысль — в конце концов, в данный момент мы ищем причину, а не решение, поэтому можно не удалять заголовок, а просто добавить его к запросам браузера. Ведь, если фильтрация ведется именно по этому заголовку, браузеру также должно быть отказано в доступе.
Браузер логинился отлично…
Because It's Red!
Из трех вариантов у нас остался только один — cookies. Итак, в нашем запросе из Flash мы видим куки с именами l и p. Судя по всему, l это идентификатор логинящегося пользователя, а p — хэш пароля. При логине через браузер они устанавливаются в ответе от сервера.

В данном процессе меня заинтересовал другой момент — при повторном логине браузер НЕ отправляет эти куки на сервер. А Flash отправляет. И получает за это «по шапке». А знаете почему это все происходит? Потому что, перед тем как «заходить» надо сначала «выйти» :-)
Думаю, скриншот выхода из Vkontakte через браузер объяснит вам многое.
]
А когда ВЫ в последний раз «выходили» из Вконтакта в своем приложении?
Думаю, данная проблема актуальна и для PHP, если вы не храните cookies в файлах со случайными именами.
За сим прощаюсь. Надеюсь был полезен.