Функция авторизации через 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 синтаксис »

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

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

Комментарии


2
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);