Разное → Прямая авторизация ВКонтакте перестала работать

С 17.06.2015 прямая авторизация ВКонтакте через логин и пароль перестала работать. Речь идет не об авторизации через OAuth, а именно через отправку GET запросов с помощь Curl PHP, имитирующих браузер.

Для чего этого необходимо? Для вызова некоторых функций Вконтакте, которые не доступны через API Вконтакте, или из-за существующий ограничений.

Раньше достаточно было отправить GET запрос наhttp://login.vk.com/?act=login передав параметры&email=*** (логин) и &pass=*** (пароль). С недавних пор авторизация не происходит, вместо этого производится переадрессация по адресу:

http://vk.com/login.php?&to=&s=0&m=1&email=

Решение

Для того, чтобы произвести авторизацию необходимо отправить запрос на авторизацию по адресу https://login.vk.com/?act=login. Для этого нужно использовать POST запрос, в котором кроме логина и пароля необходимо указать следующие параметры:

act: login
role: al_frame
ip_h: <ip_h>
lg_h: <lg_h>
email: <логин>
pass: <пароль>
expire: 
captcha_sid: 
captcha_key: 
_origin: http://vk.com
q: 1

Из важного: добавились параметры ip_h и lg_h , которе легко парсятся со страницы http://vk.com и выглядят так:

<input type="hidden" name="ip_h" value="47bf161c03f465d43a"/>
<input type="hidden" name="lg_h" value="3f4654161cd43f07bf"/>

Алгоритм авторизации Вконтакте на PHP становится следующим:

1. С помощью CURL открываем http://vk.com и парсим значения ip_h и lg_h. Простенькие регулярки будут иметь вид:

preg_match('/<input type="hidden" name="ip_h" value="(.+)" \/>/i', $vk_html, $ip_h);
preg_match('/<input type="hidden" name="lg_h" value="(.+)" \/>/i', $vk_html, $lg_h)

2. Передаем полученные значения вместе с остальными параметрами POST запросом на url https://login.vk.com/?act=login. В итоге запрос будет иметь приблезительно такой вид:

https://login.vk.com/?act=login&ip_h=***&lg_h=***&role=al_frame&email=***&pass=***&expire=&captcha_sid=&captcha_key=&_origin=http://vk.com&q=1

3. Сохраняем куки в файл и вызываем необходимую страницу Вконтакте для парсинга, например https://vk.com/feed?section=photos

curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');

Проделайте предварительно п.1 и п.2 вручную чтоб убедится что все работает, получив предварительно значения ip_h и lg_hчерез исходный код страницы (комбинация Ctrl+U в браузере). В результате вас должно перенаправить на пустую страницу, а в адресной строке должно содержатся некое значение __q_hash.

  • Алексей

    Доброго времени суток. У Вас получилось описанным в этом посте
    методом авторизоваться? Пытаюсь так делать, но куки удаляются, а не
    устанавливаются (remixq)

    $url = ‘http://login.vk.com/?act=login’;
    $cl = curl_init($url);
    curl_setopt($cl, CURLOPT_USERAGENT, «Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0″);
    curl_setopt($cl, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($cl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($cl, CURLOPT_VERBOSE, 1);
    curl_setopt($cl, CURLOPT_HEADER, 1);
    curl_setopt($cl, CURLOPT_POST, true);
    curl_setopt($cl,
    CURLOPT_POSTFIELDS,
    ‘act=login&ip_h=ЗДЕСЬМОЁЗНАЧЕНИЕ&lg_h=ЗДЕСЬМОЁЗНАЧЕНИЕ&role=al_frame&email=ЗДЕСЬМОЁЗНАЧЕНИЕ&pass=ЗДЕСЬМОЁЗНАЧЕНИЕ&expire=&captcha_sid=&captcha_key=&_origin=http://vk.com&q=1’);
    curl_setopt($cl, CURLOPT_SSL_VERIFYPEER, FALSE);
    echo curl_exec($cl);

    Вот ответ:

    HTTP/1.1
    302 Found Server: Apache Date: Mon, 22 Jun 2015 23:07:26 GMT
    Content-Type: text/html; charset=windows-1251 Content-Length: 0
    Connection: keep-alive X-Powered-By: PHP/3.14926 Set-Cookie:
    remixlang=3; expires=Thu, 16 Jun 2016 20:38:42 GMT; path=/;
    domain=.vk.com Pragma: no-cache Cache-control: no-store P3P: CP=»IDC DSP
    COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT» Location:
    http://vk.com/login.php?act=slogin&to=&s=0&m=4&email=
    HTTP/1.1 200 OK Server: Apache Date: Mon, 22 Jun 2015 23:07:27 GMT
    Content-Type: text/html; charset=windows-1251 Content-Length: 308
    Connection: keep-alive X-Powered-By: PHP/3.14926 Set-Cookie:
    remixlang=3; expires=Fri, 17 Jun 2016 21:28:05 GMT; path=/;
    domain=.vk.com Set-Cookie: remixmid=DELETED; expires=Thu, 01 Jan 1970
    00:00:01 GMT; path=/; domain=.vk.com Set-Cookie: remixsid=DELETED;
    expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/; domain=.vk.com
    Set-Cookie: remixsid6=DELETED; expires=Thu, 01 Jan 1970 00:00:01 GMT;
    path=/; domain=.vk.com Set-Cookie: remixgid=DELETED; expires=Thu, 01 Jan
    1970 00:00:01 GMT; path=/; domain=.vk.com Set-Cookie:
    remixemail=DELETED; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/;
    domain=.vk.com Set-Cookie: remixpass=DELETED; expires=Thu, 01 Jan 1970
    00:00:01 GMT; path=/; domain=.vk.com Set-Cookie: remixapi_sid=DELETED;
    expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/; domain=.vk.com
    Set-Cookie: remixpermit=DELETED; expires=Thu, 01 Jan 1970 00:00:01 GMT;
    path=/; domain=.vk.com Set-Cookie: remixsslsid=DELETED; expires=Thu, 01
    Jan 1970 00:00:01 GMT; path=/; domain=.vk.com Pragma: no-cache
    Cache-control: no-store P3P: CP=»IDC DSP COR ADM DEVi TAIi PSA PSD IVAi
    IVDi CONi HIS OUR IND CNT»

  • Поделитесь своим решением

  • Дмитрий

    Предоставьте пожалуйста пример работы

  • Александр

    Добрый день. А не подскажете, какой запрос отправлять после получения и обработки капчи — пытался тот же самый, с подстановкой captcha_sid, captcha_key, но так ничего и не вышло

  • Роман Кистин

    Может надо куки в файле хранить
    curl_setopt($cl, CURLOPT_COOKIEFILE, $file_cookie);
    curl_setopt($cl, CURLOPT_COOKIEJAR, $file_cookie);
    $file_cookie — путь к файлу с куками.

  • Александр

    Всё, вышло

  • Artem Chapaev

    Вот у меня тоже самое выдает.
    У кого получилось подскажите как решить, пжл.

  • Artem Chapaev

    Заработало.
    У меня решилось когда путь к файлу куков сделал абсолютным (/var/www/…/cookie) и в папке с правами 777.
    curl_setopt($cl, CURLOPT_COOKIEFILE, $file_cookie);
    curl_setopt($cl, CURLOPT_COOKIEJAR, $file_cookie);
    $file_cookie — путь к файлу с куками.

  • Павел Павленко

    Людии, ну будьте людьми, скиньте кто нибудь полный код по авторизации ВК. Желательно что бы на выходе получалась переменная с полученной страницей пользователя. Пол дня уже сижу, не могу понять ЧТО переделать в прошлых кодах, что бы заработало наконец.

  • Дмитрий

    Можешь выложить полный код?

  • Владислав

    можно рабочий пример пожалуйста? :)

  • Павел Павленко

    Привет. Ты нашел рабочий код авторизации? у меня почему то вместо получения страницы пустая переменная выходит. хотя ip_h и lg_h нормально получает

  • Павел Павленко

    Привет. у Вас есть рабочйи код авторизации?

  • Алексей

    Добрый день, Артем.
    Можете прислать получившийся код?

  • Сергей

    Есть рабочий код?

  • Hexy Gopher

    func AuthUser(login string, password string) (*http.Cookie, error) {
    var remixlhk *http.Cookie
    var remixsid *http.Cookie
    response, err := http.Get(origin)
    if err != nil {
    return nil, err
    }
    cookies := response.Cookies()
    for _, cookie := range cookies {
    if cookie.Name == «remixlhk» {
    remixlhk = cookie
    }
    }
    if remixlhk == nil {
    return nil, errors.New(«Cookie remixlhk not found»)
    }
    defer response.Body.Close()
    body, err := ioutil.ReadAll(response.Body)
    if err != nil {
    return nil, err
    }
    lgi := strings.Index(string(body), «lg_h=»)
    lgh := string(body[lgi+5 : lgi+23])
    data := url.Values{«email»: {login}, «pass»: {password}}
    request, err := http.NewRequest(«POST», authURL+»lg_h=»+lgh, bytes.NewBufferString(data.Encode()))
    if err != nil {
    return nil, err
    }
    request.AddCookie(remixlhk)
    http.DefaultClient.CheckRedirect = func(req *http.Request, via []*http.Request) error { return errors.New(«») }
    response, _ = http.DefaultClient.Do(request)
    u, err := response.Location()
    if err != nil {
    return nil, err
    }
    response, _ = http.Get(u.String())

    cookies = response.Cookies()
    for _, cookie := range cookies {
    if cookie.Name == «remixsid» {
    remixsid = cookie
    }
    }
    if remixsid == nil {
    return nil, errors.New(«Cookie remixsid not found»)
    }
    return remixsid, nil
    }

  • Олег

    Я только что закончил писать функцию авторизации для вконтакте на делфи.Этот код на данный момент работает :
    function login(login,pass : string) : string;
    var
    response,res,twourl,Cookie, cookz,url : string;
    param,cooklist : TStringList;
    i : integer;

    begin

    // Создание объектов ——————————————
    http := TIdHTTP.Create ; //
    SSLIOHandlerSocket:= TIdSSLIOHandlerSocketOpenSSL.Create; //
    param := TStringList.Create; //
    cooklist:= TStringList.Create; //
    //————————————————————

    //Настройки http SSLIOHandlerSocket ————————
    SSLIOHandlerSocket.SSLOptions.Method := sslvTLSv1; //
    SSLIOHandlerSocket.SSLOptions.Mode:= sslmUnassigned; //
    //
    //Инициализация http—————————————-
    http.IOHandler:= SSLIOHandlerSocket; //
    http.HandleRedirects:= true; //
    http.Request.Connection:=’keep-alive’; //
    http.Request.UserAgent:=’Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0.1′;
    //
    //
    //
    //———————————————————-
    //
    response:= http.Get(‘http://m.vk.com’);//запрос страницы //
    sleep(1000); //
    http.Response.RawHeaders.Extract (‘Set-Cookie’, cooklist);//
    //Заполнение параметров для POST-запроса———————
    //param.Add(‘act=login’) ; //
    param.Add(‘_origin=http://m.vk.com’) ; //
    param.Add(‘ip_h=’+pars(response,’ip_h=’,5,18)) ; //
    param.Add(‘lg_h=’+pars(response,’lg_h=’,5,18)) ; //
    param.Add(‘role=pda’) ; //
    param.Add(‘utf8=1′) ; //
    param.Add(’email=’+login) ; //
    param.Add(‘pass=’+pass) ; //
    //———————————————————-

    //Обработка редиректа 302 через исключение——————

    try //cоздаем конструкцию try…except для отключения ошибок
    http.HandleRedirects:= false; // отключаем редирект
    http.Post(‘https://login.vk.com/?act=login’,param) ; //посылаем запрос на котором может быть редирект

    except
    if (HTTP.Response.ResponseText=’HTTP/1.1 302 Found’) then //Если сервер ответил нам редиректом то
    sleep(1000);
    url:= http.Response.Location ; // Достаем адрес редиректа из заголовка ответа сервера
    http.HandleRedirects:= true; // Включаем авторедирект
    if pos(‘Выход’,http.Get(url))>0 then // Если на странице есть слово Выход то авторизация удалась

    Result:= ‘OK’;

    end;//конец конструкции try…except

    end;

    Я авторизуюсь для использования апи вконтакте. Не ставлю никаких куки после авторизации и получаю токен при запросе : http.Get(‘https://oauth.vk.com/authorize?client_id=5129725&display=mobile&redirect_uri=https://oauth.vk.com/blank.html&scope=friends&response_type=token&v=5.44’) ;