Загрузка...

Функция авторизации через VK

В заметке описывается функция-заготовка, предназначенная для авторизации на сайте пользователей из ВКонтакте


Функция, описываемая в заметке, реализует только лишь проверку и получение данных о пользователе из соц. сети ВКонтакте в ваше приложение. В зависимости от того на каком движке разработан сайт, данные пришедшие от VK, можно обработать соответствующим образом в контексте того или иного движка или системы.

Сперва нужно настроить приложение во вконтакте. Создаем приложение:


create-app-vk


Затем редактировать » настройки, здесь нам понадобится id приложения, защищенный ключ, проставить базовый домен и проверить, чтобы был вкл. API, пример:


edit-app-vk

function auth_VK($id, $secret_key, $uri)
{
    if (!isset($_REQUEST['error'])) {
        $client_id = $id;
        $client_secret_key = $secret_key;
        $redirect_uri = $uri;
        $oauth_url = '';
        if (isset($_REQUEST['code']) && !empty($_REQUEST['code'])) {
            $code = trim(strip_tags($_REQUEST['code']));
            $params = [
                'client_id' => $client_id,
                'client_secret' => $client_secret_key,
                'code' => $code,
                'redirect_uri' => $redirect_uri
            ];
            $myCurl = curl_init();
            curl_setopt_array($myCurl, [
                CURLOPT_URL => 'https://oauth.vk.com/access_token',
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_POSTFIELDS => urldecode(http_build_query($params))
            ]);
            if ($chek = curl_exec($myCurl)) {
                $token = json_decode($chek);
                if ($token->error) {
                    /* Ошибка авторизации через VK! Смотрим коды ошибки
                     * Выкидываем исключение или выдаем сообщение
                     * Обрабатваем эту ситуацию
                     *  */
                } else {
                    /*
                     * Получение данных
                     * */
                    $email = $token->email;
                    if (isset($token->access_token)) {
                        $params = [
                            'uids' => $token->user_id,
                            'fields' => 'first_name,last_name,screen_name,bdate,photo_big',
                            'access_token' => $token->access_token
                        ];
                        curl_setopt_array($myCurl, [
                            CURLOPT_URL => 'https://api.vk.com/method/users.get',
                            CURLOPT_RETURNTRANSFER => true,
                            CURLOPT_POSTFIELDS => urldecode(http_build_query($params))
                        ]);
                        if ($chek = curl_exec($myCurl)) {
                            $info = json_decode($chek);
                            $uid = $info->response[0]->uid;
                            $first_name = $info->response[0]->first_name;
                            $last_name = $info->response[0]->last_name;
                            $bdate = $info->response[0]->bdate;
                            $photo_big = $info->response[0]->photo_big;
                            /*
                             * На этом этапе регистрация и авторизация пользователя
                             * Проверка на существующего пользователя, генерация пароля и тд
                             * Проверить на наличие в бд и зарегистриовать, или авторизовать пользователя
                             * детали реализации дальше опущены
                             * */
                        }
                    }
                }
            }
            curl_close($myCurl);
        } else {
            $params = [
                'client_id' => $client_id,
                'redirect_uri' => $redirect_uri,
                'display' => 'popup',
                'scope' => 'email',
                'response_type' => 'code'
            ];
            $oauth_url = 'https://oauth.vk.com/authorize?' . urldecode(http_build_query($params));
        }
        return ($oauth_url !== '') ? $oauth_url : false;
    } else {
        return false;
    }
}

Сама функция возвращает либо ссылку, которую можно повесить на кнопку "Войти через VK", либо false (в случае, когда пользователь успешно авторизовался или вывелась ошибка, в случае неудачной проверки, или по иным причинам). Там где должна выводится ссылка:

/*  инициализируем авторизацию, 
 * $redirect_uri — куда будет идти перенаправление, string
 *  например страница входа — site.com/login
 * $id — id приложения в ВК, integer
 * $secret_key — секретный ключ, string
 */

if ($oauth_url = auth_VK($id, $secret_key, $redirect_uri)){ 
   // $oauth_url содержит ссылку на авторизацию через VK
   ?><p><a href="<?= $oauth_url ?>" class="btn">Войти через VK</a></p><?
}

В качестве теста я создал приложение, в настройках выбрал всю необходимую информацию. Пошел проверять у себя на localhost в теме twentyseventeen на wordpress. Создал там страничку auth, шаблон:

<? get_header(); ?>
    <div class="wrap">
        <div id="primary" class="content-area">
            <main id="main" class="site-main" role="main">
                <?
                if ($oauth_url = auth_VK(5812210, 'vm0DqCqNPXyR1aAf0nTs', 'http://site.loc/auth/')) {
                    ?><p><a href="<?= $oauth_url ?>" class="btn">Войти через VK</a></p><?
                }
                ?>
            </main>
            <!-- #main -->
        </div>
        <!-- #primary -->
    </div><!-- .wrap -->
<? get_footer(); ?>

Clip2net_170226013902-min

А в файл functions.php саму функцию auth_VK. Только в самом конце подправил функцию, чтобы посмотреть возвращаемый результат:

/*
    * На этом этапе регистрация и авторизация пользователя
    * Проверка на существующего пользователя, генерация пароля и тд
    * Проверить на наличие в бд и зарегистриовать, или авторизовать пользователя
    * детали реализации дальше опущены
    * */
       echo '<pre>';
          var_dump( [
             'id' => $uid,
             'first_name' => $first_name,
             'last_name' => $last_name,
             'bdate' => $bdate,
             'photo_big' => $photo_big
           ] );
       echo '</pre>';

В самом начале при заходе на страницу auth, показывается ссылка на вход через вк. Как видно из скриншота после перехода по ссылке, к нам на сайт приходят все данные пользователя, которые мы в дальнейшем сможем обработать:

Clip2net_170226003913-min

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

/*
 * Проверить на наличие в бд и внести пользователя или авторизовать
 * */
global $wpdb;
$query = "SELECT * FROM `wp_users` WHERE `user_email` = '$email'";
$chekmail = $wpdb->get_results($query);
if (count($chekmail) == 0) {
    /*
     * Пользователя нет в БД
     * */
    $pass = wp_generate_password();
    /*
     * Зарегистрировать
     * */
    $userdata = [
        'ID' => 0
        , 'user_pass' => $pass
        , 'user_login' => $email
        , 'user_nicename' => 'vk_' . $uid
        , 'user_email' => $email
        , 'display_name' => $first_name
        , 'first_name' => $first_name
        , 'last_name' => $last_name
        , 'description' => 'Пользователь, авторизованный через VK'
        , 'rich_editing' => true
        , 'role' => 'subscriber'
    ];
    wp_insert_user($userdata);
    /*
     * Авторизовать по паролю
     * */
    $credentials = [
        'user_login' => $email,
        'user_password' => $pass
    ];
    if (is_wp_error($user = wp_authenticate($credentials['user_login'], $credentials['user_password']))) {
        // Ошибка
        ?><p class="alert alert-danger"><?= $user->get_error_message() ?></p><?
    } else {
        nocache_headers();
        wp_clear_auth_cookie();
        wp_set_auth_cookie($user->ID);
        wp_redirect($uri);
        /*
         * Отправить на емаил pass к аккаунту
         * */
        $to = [$email];
        $headers = 'MIME-Version: 1.0' . "\r\n";
        $headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
        $headers .= 'From: site.loc <admin@site.loc>' . "\r\n";
        $subj = "Спасибо за регистрацию в блоге";
        $what = "<h3>Спасибо за регистрацию в блоге, через VK, " . $first_name . "!</h3>";
        $what .= "<p>Привет! Твой пароль: " . $pass . " , логин — " . $email . " , если заходишь через /wp-admin/ , или просто на странице /auth/ все также через VK</p>";
        wp_mail($to, $subj, $what, $headers);
    }
} else {
    /*
     * Пользователь уже зарегистрирован, просто авторизовать
     * ...
     * */
}


Похожие заметки:

Капча в пользовательских формах

Модули » Капча

Расположение » Каталог плагинов WordPress

Сaptcha генерирует цифры и латинские буквы. Предназначен для использования в пользовательских формах и отображается простым шорткодом, автоматически подключается к форме входа.

Открыть здесь

Перенос WordPress сайта на новый домен

Способы разворачивания сайта под управлением WordPress на других доменных адресах

Открыть здесь

Ajax контакт форма на WordPress

Создаем AJAX форму обратной связи на WordPress c использованием капчи jblog-captcha

Открыть здесь


Перед тем как писать комментарии, рекомендую ознакомиться:

Markdown синтаксис »

Оформление кода »

Нужна аватарка »

Комментарии


8
avatar

Вася сказал 31-07-2018 в 11:50


Добрый день! а можно код именно авторизации а не регистрации?


avatar

Админ

Роман Жариков сказал 08-05-2019 в 14:53

   В ответ на комментарии автора Вася
//...

$user = wp_authenticate($credentials['user_login'], $credentials['user_password']);

// это вынести в отдельную функцию можно, так как этот код повторяется
nocache_headers();
wp_clear_auth_cookie();
wp_set_auth_cookie($user->ID);
wp_redirect($uri);

avatar

серега сказал 07-10-2019 в 21:23


доброе время суток.подскажите.я немного не понял про code. у меня на главное странице. показывает http://мой сайт.ru/?code=6eb1264f8d4029e3f7 при нажатии кнопки- войти через вконтакте.пока грузится то показывает http://мой сайт.ru/vk/ а когда прогрузится снова показывает http://мой сайт.ru/?code=5ab3264d8g4029e2h3 вообщем.сколько не жми на вход.меняется только code= в чем проблема?


avatar

Админ

Роман Жариков сказал 07-10-2019 в 22:26

   В ответ на комментарии автора серега

Добрый вечер. Заметку писал давно, так что код, описанный в данном контексте требует жесточайшего рефакторинга. Не удивительно, что в нем мало чего понятно насчёт параметра code :).

В общем случае с этим параметром, вы должны сделать запрос на эндпоинт oauth.vk.com/access_token, для получения токена доступа (возможно он имеет некоторый expires, значит нужен механизм сохранения и перезапроса его), а дальше с этим токеном вам открывается доступ к апи на получение данных. Подробнее можно почитать ВК гайды по работе со всем этим. Но, как правило, в любом нормальном фреймворке или cms есть пакеты/плагины для этих вещей, так что лучше использовать их, вместо того чтобы использовать низкоуровневые реализации.


avatar

серега сказал 07-10-2019 в 22:52


сначала код получил. потом токен .токен живучий а инфы по этой теме найти не могу.то ли в скрипте где то ошибка то ли в самой регистрации


avatar

Админ

Роман Жариков сказал 07-10-2019 в 23:17

   В ответ на комментарии автора серега

Вот эти все вещи, если вы программируете не на голом php, к примеру, скрыты от вас. То есть детали реализации схемы oauth скрыты за ясным интерфейсом конкретной библиотеки, конкретного провайдера (в данном случае ВК). Имеется ввиду что вы всего лишь в файле конфигурации или настройках плагина (если это cms-ка какая-то) задаёте идентификатор приложения, секретный ключ, выданный вам со страницы настроек вк, задаёте ещё какие-нибудь специфические параметры (если надо) и все. Весь код в грубом приближении, который в этой заметке показан, что называется работает "под капотом". В вашем клиентском коде, вы должны оперировать только методами получения данных и сохранением сущности пользователя с привязкой к данной соц. сети с последующей его авторизацией. При повторном обращении, пользователь просто авторизуется.


avatar

Адель сказал 19-10-2019 в 05:32

   В ответ на комментарии автора Роман Жариков

Друг привет )) могу тебя попросить о просьбе?1) Заинтересовал твой ответ, есть предложение )


avatar

Админ

Роман Жариков сказал 19-10-2019 в 10:52

   В ответ на комментарии автора Адель

Приветствую. Можете писать на почтовый ящик roman@zharrikov.ru, тут следует оставлять комментарии по существу.