Информация к новости
  • Просмотров: 1039
  • Автор: sulicompany
  • Дата: 6-04-2013, 09:52
 (голосов: 0)
6-04-2013, 09:52

Аутентификация через ВКонтакте

Категория: Программирование » PHP


 

 

С каждым днём влияние социальных сетей и сервисов только крепчает. Это означает, что нам, как веб разработчикам нужно это учитывать. Сегодня я расскажу и покажу, как создать аутентификацию ваших пользователей через социальную сеть ВКонтакте. Для этого мы не будем пользоваться какими-то сторонними библиотеками, а реализуем всё с нуля, собственными руками. Думаю, многие ждали подобного урока, так что томить не буду. Начнём!

 

 

Заметка. Пример, созданный в данном уроке, предназначен для работы на локальном сервере.

Шаг 1. Регистрация нового приложения

Для начала нам необходимо создать новое приложение на сайте социальной сети 

В открывшейся форме введите название приложения; выберите тип “Веб-сайт”; В качестве адреса сайта введите путь к папке с проектом на вашем локальном сервере. В моём случае, это http://localhost/vk-auth. Базовый домен:localhost.

После нажатия на кнопку “Подключить сайт”, вам наверняка придётся ввести проверочный код, который придёт по смс. Если вы пройдёте проверку, то вам должна открыться следующая форма с настройками приложения.

Сразу же хочу предупредить, что настоящие данные, относящиеся к моему приложению, я заменил на фиктивные, т.к. публикация таких значений как “Защищённый ключ” карается удалением вашего приложения или учётной записи в целом.

Из данной формы нам понадобятся такие данные, как `ID приложения`, `Защищённый ключ`, `Адрес сайта`. Запишем их в специальные переменные в файле index.php:

1 <?php
2  
3 $client_id '3485070'// ID приложения
4 $client_secret 'lYjfUZwZmlJJlFIqQFAj'// Защищённый ключ
5 $redirect_uri ''; // Адрес сайта

Шаг 2. Генерация ссылки для аутентификации

Для генерации ссылки нам потребуется адрес аутентификации и специальные параметры:

1 $url '';
2  
3 $params array(
4     'client_id'     => $client_id,
5     'redirect_uri'  => $redirect_uri,
6     'response_type' => 'code'
7 );

С помощью функции http_build_query, передав туда массив параметров, получим чередование ключей и значений, как в url адресе. Итак, генерируем ссылку и выводим на экран:

1 echo $link '<p><a href="' $url '?' . urldecode(http_build_query($params)) . '">Аутентификация через ВКонтакте</a></p>';

Также тут я воспользовался функцией urldecode. Если этого не сделать, то в сгенерированной ссылке могут появиться закодированные символы слешей, знаков двоеточия и так далее. Что-то вроде этого:

1

Если же мы пропустим данную строку через функцию urldecode, то получим:

1

Итак, ссылка для аутентификации у нас готова. Если мы сформировали все параметры правильным образом и получили верный url, то пройдя по ссылке, будем перенаправлены по адресу, указанному в настройках приложения ('http://localhost/vk-auth'). Только теперь к этому адресу будет прикреплён специальный параметр code:

1 // Пример. В вашем случае код будет другой
2 http://localhost/vk-auth/?code=f30621b146115b3bad

Шаг 3. Получение токена

Начинать процедуру аутентификации мы можем тогда и только тогда, когда к нам пришёл параметр code. Он нам нужен для того, чтобы получить специальный токен доступа, с помощью которого, в дальнейшем, мы достанем информацию о пользователе.

В первую очередь, снова сформируем нужные нам параметры для этого запроса:

1 if (isset($_GET['code'])) {
2     $params array(
3         'client_id' => $>clientId,
4         'client_secret' => $this->clientSecret,
5         'code' => $_GET['code'],
6         'redirect_uri' => $this->redirectUri
7     );
8 }

Далее нам нужно отправить GET запрос на адрес https://oauth.vk.com/access_token, передав перечисленные параметры. В PHP выполнить GET запрос по какому-то адресу можно несколькими способами. Для данного урока я воспользуюсь функцией file_get_contents.

01 if (isset($_GET['code'])) {
02     $params array(
03         'client_id' => $client_id,
04         'client_secret' => $client_secret,
05         'code' => $_GET['code'],
06         'redirect_uri' => $redirect_uri
07     );
08  
09     $token = json_decode(file_get_contents('' '?' . urldecode(http_build_query($params))), true);
10 }

В результате, при успешном выполнении запроса в переменную $token будет записан ответ от ВКонтакте в JSON формате. Данная строка содержит 3 параметра: access_token, который мы будем использовать в следующих запросах для извлечения информации о пользователе, expires_in - время жизни токена, user_id - id пользователя, который прошёл аутентификацию.

1 {"access_token":"2c6276b767b5e2f35f908e89d61416beea17b6d1ebcd3d14e20ac910281d306bb506ec78e75518ed614e9","expires_in":86399,"user_id":14966712}

Для того чтобы мы далее могли работать с данными параметрами, декодируем JSON строку с помощью функцииjson_decode и помещаем данные в массив, передав в качестве второго аргумента true.

Шаг 4. Получение информации о пользователе

Итак, теперь когда у нас есть параметры access_token и user_id, мы можем сделать запрос к ВКонтакте API и получить информацию о пользователе. Для начала снова подготовим массив с параметрами, которые в последствии превратим в фрагмент url строки.

01 if (isset($_GET['code'])) {
02     $params array(
03         'client_id' => $client_id,
04         'client_secret' => $client_secret,
05         'code' => $_GET['code'],
06         'redirect_uri' => $redirect_uri
07     );
08  
09     $token = json_decode(file_get_contents('' '?' . urldecode(http_build_query($params))), true);
10  
11     if (isset($token['access_token'])) {
12         $params array(
13             'uids'         => $token['user_id'],
14             'fields'       => 'uid,first_name,last_name,screen_name,sex,bdate,photo_big',
15             'access_token' => $token['access_token']
16         );
17     }
18 }

В параметр uids записываем id пользователя; в fields перечисляем через запятую поля, которые хотим извлечь (uid - id пользователя, first_name - имя, last_name - фамилию, screen_name - имя отображаемое на страницах VK, sex - пол, bdate - дату рождения, photo_big - фотографию). Для доступа к большему количеству полей обратитесь к ВКонтакте API . В качестве последнего параметра передаём 'access_token'.

Для получения информации о пользователе сфомированные параметры нам нужно отправить GET запросом по адресу https://api.vk.com/method/users.get.

01 if (isset($_GET['code'])) {
02     $params array(
03         'client_id' => $client_id,
04         'client_secret' => $client_secret,
05         'code' => $_GET['code'],
06         'redirect_uri' => $redirect_uri
07     );
08  
09     $token = json_decode(file_get_contents('' '?' . urldecode(http_build_query($params))), true);
10  
11     if (isset($token['access_token'])) {
12         $params array(
13             'uids'         => $token['user_id'],
14             'fields'       => 'uid,first_name,last_name,screen_name,sex,bdate,photo_big',
15             'access_token' => $token['access_token']
16         );
17  
18         $userInfo = json_decode(file_get_contents('' '?' . urldecode(http_build_query($params))), true);
19     }
20 }

В результате, если всё было сделано правильно, то получим JSON ответ следующего вида:

1 {"response":[{"uid":14966712,"first_name":"Стас","last_name":"Протасевич","screen_name":"stanislav.protasevich","sex":2,"bdate":"3.7.1988","photo_big":"http:\/\/cs307601.vk.me\/u14966712\/a_8234a279.jpg"}]}

Снова преобразуем JSON ответ в массив и обратимся к нулевому элементу, хранящемуся в массиве, доступному по ключу response:

01 if (isset($_GET['code'])) {
02     $result = false;
03     $params array(
04         'client_id' => $client_id,
05         'client_secret' => $client_secret,
06         'code' => $_GET['code'],
07         'redirect_uri' => $redirect_uri
08     );
09  
10     $token = json_decode(file_get_contents('' '?' . urldecode(http_build_query($params))), true);
11  
12     if (isset($token['access_token'])) {
13         $params array(
14             'uids'         => $token['user_id'],
15             'fields'       => 'uid,first_name,last_name,screen_name,sex,bdate,photo_big',
16             'access_token' => $token['access_token']
17         );
18  
19         $userInfo = json_decode(file_get_contents('' '?' . urldecode(http_build_query($params))), true);
20         if (isset($userInfo['response'][0]['uid'])) {
21             $userInfo $userInfo['response'][0];
22             $result = true;
23         }
24     }
25 }

Прошу обратить внимание, что в данном фрагменте, я добавил специальную переменную $resut, равную изначально false сразу же после проверки наличия GET параметра code. Если нам удалось извлечь информацию о пользователе, то мы меняем значение этой переменной на true.

Полный код:

01 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
02         "">
03 <html xmlns="" xml:lang="ru">
04 <head>
05     <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
06     <title></title>
07 </head>
08 <body>
09     <?php
10  
11     $client_id '3485070'// ID приложения
12     $client_secret 'lYjfUZwZmlJJlFIqQFAj'// Защищённый ключ
13     $redirect_uri ''; // Адрес сайта
14  
15     $url '';
16  
17     $params array(
18         'client_id'     => $client_id,
19         'redirect_uri'  => $redirect_uri,
20         'response_type' => 'code'
21     );
22  
23     echo $link '<p><a href="' $url '?' . urldecode(http_build_query($params)) . '">Аутентификация через ВКонтакте</a></p>';
24  
25 if (isset($_GET['code'])) {
26     $result = false;
27     $params array(
28         'client_id' => $client_id,
29         'client_secret' => $client_secret,
30         'code' => $_GET['code'],
31         'redirect_uri' => $redirect_uri
32     );
33  
34     $token = json_decode(file_get_contents('' '?' . urldecode(http_build_query($params))), true);
35  
36     if (isset($token['access_token'])) {
37         $params array(
38             'uids'         => $token['user_id'],
39             'fields'       => 'uid,first_name,last_name,screen_name,sex,bdate,photo_big',
40             'access_token' => $token['access_token']
41         );
42  
43         $userInfo = json_decode(file_get_contents('' '?' . urldecode(http_build_query($params))), true);
44         if (isset($userInfo['response'][0]['uid'])) {
45             $userInfo $userInfo['response'][0];
46             $result = true;
47         }
48     }
49  
50     if ($result) {
51         echo "Социальный ID пользователя: " $userInfo['uid'] . '<br />';
52         echo "Имя пользователя: " $userInfo['first_name'] . '<br />';
53         echo "Ссылка на профиль пользователя: "