Аутентификация через «вконтакте»

Краткое введение в OAuth

Лучший способ представить OAuth — перечислить список событий, которые происходят во время входа:


  • Обработка отправки формы. Пользователь переходит на домашнюю страницу приложения, например http://www.example.com, и нажимает кнопку «Sign In with Facebook», которая ссылается на маршрут приложения, например .
  • Fetch Request Token (внутренний запрос). Сервер получает запрос и отвечает перенаправлением на URL авторизации OAuth Facebook. Все провайдеры OAuth должны документировать URL-адрес для перенаправления пользователя.
    • В запросе передается Consumer key — «логин приложения», а сам запрос подписывается при помощи Consumer secret — «пароля приложения», что защищает его от подделки.
    • В ответ Provider генерирует и возвращает «заполненный мусором» токен, который называется Request Token.
  • Redirect to Authorization (через редирект в браузере). Теперь пользователю предлагается войти в систему Facebook (если уже не вошел в систему). Затем предоставляется запрос об обмене информацией, когда пользователю необходимо предоставить разрешение Facebook для совместного использования запрошенной информации с исходным приложением. Все это делается на веб-сайте Facebook и является частной транзакцией между Facebook и пользователем, приложение не участвует.
  • Fetch Access Token (внутренний запрос). После того, как пользователь принимает запрос на обмен информацией, Facebook перенаправляет обратно в приложение по предварительно настроенному URL-адресу обратного вызова, например . Строка запроса URL-адреса переадресации включает в себя код авторизации, который приложение может использовать для доступа к API Facebook от имени пользователя.
  • Call API (внутренний запрос). Приложение использует API Facebook для получения информации о пользователе. Особый интерес представляет собой уникальный идентификатор пользователя ( Shared Secret ), который может использоваться для регистрации пользователя в базе данных приложения после регистрации пользователя для входа в систему.

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

В настоящее время используются две версии протокола OAuth, как в соответствии с описанным выше общим процессом, так и с некоторыми различиями в реализации. OAuth 1.0a, используемый Twitter, является самым сложным из двух. OAuth 2, используемый Facebook, представляет собой несовместимую пересмотренную версию протокола, которая устраняет большую часть сложности версии 1.0a, полагаясь на защищенный HTTP для шифрования.

5 последних уроков рубрики «PHP»

Когда речь идёт о безопасности веб-сайта, то фраза «фильтруйте всё, экранируйте всё» всегда будет актуальна. Сегодня поговорим о фильтрации данных. Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак

В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода. Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение

В этой статье мы расскажем как улучшили процесс подключение нескольких модулей. Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке. Подборка PHP песочниц Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.

Шаг 5. Извлечение информации о пользователе

Теперь извлекать информацию о пользователе мы можем из массива, хранящегося в переменной $userInfo, по ключам uid, name, gender, birthdate, pic_2… Для просмотра большего количества полей загляните в содержание переменной $userInfo:

if ($result) {
    echo "Социальный ID пользователя: " . $userInfo . '<br />';
    echo "Имя пользователя: " . $userInfo . '<br />';
    echo "Ссылка на профиль пользователя: " . 'http://www.odnoklassniki.ru/profile/' . $userInfo . '<br />';
    echo "Пол пользователя: " . $userInfo . '<br />';
    echo "День Рождения: " . $userInfo . '<br />';
    echo '<img src="' . $userInfo . '" />'; echo "<br />";
}

5 последних уроков рубрики «PHP»

Когда речь идёт о безопасности веб-сайта, то фраза «фильтруйте всё, экранируйте всё» всегда будет актуальна. Сегодня поговорим о фильтрации данных. Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак

В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода. Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение

В этой статье мы расскажем как улучшили процесс подключение нескольких модулей. Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке. Подборка PHP песочниц Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.

Реализация

Начнем с создания класса. При инициализации будем требовать список «разрешений», к которым приложение хочет получить доступ, id этого приложения и версию API VK. Плюсом добавим несколько необязательных параметров, значение каждого из которых прояснится далее.

Как было сказано в уже упомянутой статье, нам необходимо искусно ворочать cookie и redirect’ы. Все это за нас делает библиотека с объектом класса Session. Заведем и себе такой в поле . Для парсинга html документа используется стандартный класс из модуля . Для парсера тоже написан класс (), разбирать который большого смысла нет, так как он почти полностью повторяет таковой из упомянутой статьи. Существенное отличие лишь в том, что использованный здесь позволяет изящно отклонить авторизацию приложения на последнем шаге, если вы вдруг передумали.

Поля и будут заполнены после успешной авторизации, хранит в себе результат последнего html запроса.

Пользователю библиотеки предоставим один-единственный метод – , который совершает 3 шага:

  1. запрос на авторизацию приложения
  2. авторизация пользователя 2.1 введение кода-ключа в случае двух-факторной авторизации
  3. подтверждение разрешения на использование

Пройдемся по каждому шагу.

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

Аккуратно составляем url запроса (про параметры можно прочитать здесь), отправляем запрос и парсим полученный html.

Использование SocialAuther с несколькими социальными сетями

Теперь мы займёмся применением SocialAuther при подключении нескольких социальных сетей.

Конфигурация параметров приложений

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

$adapterConfigs = array(
    'vk' => array(
        'client_id'     => '3774741',
        'client_secret' => '3nLWEs45iWeKypmVR2CU',
        'redirect_uri'  => 'http://localhost/auth/?provider=vk'
    ),
    'odnoklassniki' => array(
        'client_id'     => '168635560',
        'client_secret' => 'C342554C028C0A76605C7C0F',
        'redirect_uri'  => 'http://localhost/auth?provider=odnoklassniki',
        'public_key'    => 'CBADCBMKABABABABA'
    ),
    'mailru' => array(
        'client_id'     => '770076',
        'client_secret' => '5b8f8906167229feccd2a7320dd6e140',
        'redirect_uri'  => 'http://localhost/auth/?provider=mailru'
    ),
    'yandex' => array(
        'client_id'     => 'bfbff04a6cb60395ca05ef38be0a86cf',
        'client_secret' => '219ba8388d6e6af7abe4b4b119cbee48',
        'redirect_uri'  => 'http://localhost/auth/?provider=yandex'
    ),
    'google' => array(
        'client_id'     => '333193735318.apps.googleusercontent.com',
        'client_secret' => 'lZB3aW8gDjIEUG8I6WVcidt5',
        'redirect_uri'  => 'http://localhost/auth?provider=google'
    ),
    'facebook' => array(
        'client_id'     => '613418539539988',
        'client_secret' => '2deab137cc1d254d167720095ac0b386',
        'redirect_uri'  => 'http://localhost/auth?provider=facebook'
    )
);

1. Ключи ‘vk’, ‘odnoklassniki’, ‘mailru’, ‘yandex’, ‘google’ и ‘facebook’ выбраны не просто так. Эти названия в дальнейшем мы будем использовать для динамического создания каждого из адаптеров.

2

Обратите внимание, что к каждому `redirect_uri` мы приписали параметр `adapter`, который равен названию соц сети. Эти ссылки (пр

http://localhost/auth?provider=facebook), вам необходимо прописать в настройках каждого из приложения. Для ВКонтакте — vk, для Одноклассников — odnoklassniki и так далее. Благодаря данному параметру `provider`, мы сможем легко определить, через какую социальную сеть пытается авторизоваться пользователь.

Создание адаптеров классов.

Как я уже говорил, названия классов адаптеров будем формировать динамически:

$adapters = array();
foreach ($adapterConfigs as $adapter => $settings) {
    $class = 'SocialAuther\Adapter\\' . ucfirst($adapter);
    $adapters = new $class($settings);
}

Для того, чтобы было яснее, возьмём маленький пример. Берём фрагмент массива параметров:

$adapterConfigs = array(
...
    'odnoklassniki' => array(
        'client_id'     => '163586560',
        'client_secret' => 'C342505C754C028C0A766C0F',
        'redirect_uri'  => 'http://localhost/auth?provider=odnoklassniki',
        'public_key'    => 'CBADCBMKABABABABA'
    ),
...

Допустим, в цикле foreach пришёл черёд данного элемента с ключом `odnoklassniki`. Название ключа записывается в переменную $adapter, а массив с параметрами — в переменную $settings. Далее первая операция создаст имя класса, а вторая задаст ему параметры и запишет адаптер в общий массив.

// имя класса формируется автоматом - SocialAuther\Adapter\Odnoklassniki($adapter);
$class = 'SocialAuther\Adapter\\' . ucfirst($adapter);

// помещаем объект класса SocialAuther\Adapter\Odnoklassniki в общий массив $adapters
$adapters = new $class($settings);

Генерация ссылок аутентификации

Теперь где-то в html коде делаем проверку на наличие GET параметра code, и если он присутствует, то мы можем выводить ссылки для аутентификации:

if (!isset($_GET)) {
    foreach ($adapters as $title => $adapter) {
        echo '<p><a href="' . $adapter->getAuthUrl() . '">Аутентификация через ' . ucfirst($title) . '</a></p>';
    }
}

Создание объекта SocialAuther для аутентификации пользователя

Создать объект SocialAuther и авторизовать пользователя мы можем, если к нам придёт GET параметр provider. Также если название адаптера совпадает хоть с одним из наших хранящихся в общем массиве, создаём объект класса SocialAuther и передаём адаптер той социальной сети, через которую авторизовался пользователь:

if (isset($_GET) && array_key_exists($_GET, $adapters)) {
	$auther = new SocialAuther\SocialAuther($adapters]);
}

Аутентификация пользователя и получение данных

Теперь, когда у нас есть объект SocialAuther, можем вызывать метод authenticate(), а затем получить данные о пользователе:

if ($auther->authenticate()) {
    $auther->getProvider();
    $auther->getSocialId();
    $auther->getName();
    $auther->getEmail();
    $auther->getSocialPage();
    $auther->getSex();
    $auther->getBirthday());
    $auther->getAvatar();
}

Прикрутка к БД

Итак, теперь когда наш основной скрипт готов, мы можем двигаться дальше и прикрутить информацию о пользователе к БД.

Создание БД и таблицы

Для данного урока создайте любую MySQL базу данных. Я назову её `auth`. В ней, с помощью данного кода, сгенерируйте таблицу:

CREATE TABLE `users` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `provider` ENUM('vk', 'odnoklassniki', 'mailru', 'yandex', 'google', 'facebook') NOT NULL,
    `social_id` VARCHAR(255) NOT NULL,
    `name` VARCHAR(255) NOT NULL,
    `email` VARCHAR(255) NOT NULL,
    `social_page` VARCHAR(255) NOT NULL,
    `sex` ENUM('male', 'female') NOT NULL,
    `birthday` DATE NOT NULL,
    `avatar` VARCHAR(255) NOT NULL
) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;

Поле id — это стандартный автоинкрементный индекс. В колонку `provider` записываем название социальной сети учётной записи пользователя. Все остальные поля соответствуют методам, которые мы можем вызвать от объекта SocialAuther для получения информации о пользователе.

Настройка подключения к БД

Данный функционал я предлагаю вынести в отдельный файл. К примеру, config.inc.php:

$db = mysql_connect('localhost', 'имя пользователя', 'пароль');
mysql_select_db('auth');
mysql_query("SET NAMES utf8");

Тут мы подключились к базе, выбрали таблицу и задали кодировку UTF8. Теперь данный файл можно присоединить к index.php и работать с таблицей.

Вставка нового пользователя

Итак, тут нам нужно предусмотреть следующее: если у нас в базе есть пользователь с социальным id и названием адаптера соц сети, которые мы получили в результате аутентификации, то пользователь уже ранее входил в нашу систему, и запись в таблице о нём есть. Если же такой записи нет, то мы должны записать нового пользователя в БД:

if ($auther->authenticate()) {

    $result = mysql_query(
        "SELECT *  FROM `users` WHERE `provider` = '{$auther->getProvider()}' AND `social_id` = '{$auther->getSocialId()}' LIMIT 1"
    );

    $record = mysql_fetch_array($result);
    if (!$record) {
        $values = array(
            $auther->getProvider(),
            $auther->getSocialId(),
            $auther->getName(),
            $auther->getEmail(),
            $auther->getSocialPage(),
            $auther->getSex(),
            date('Y-m-d', strtotime($auther->getBirthday())),
            $auther->getAvatar()
        );

        $query = "INSERT INTO `users` (`provider`, `social_id`, `name`, `email`, `social_page`, `sex`, `birthday`, `avatar`) VALUES ('";
        $query .= implode("', '", $values) . "')";
        $result = mysql_query($query);
    }
}

Тут всё происходит так, как я и говорил. Сначала проверяем, есть ли в таблице пользователь с пришедшем к нам id и provider. Если нет, то формируем массив значений, затем выполняем INSERT запрос.

Обновление данных пользователя в базе

Если в базе данных пользователь уже есть, то было бы неплохо проверить обновил ли он какие-то данные или нет. Для этого создаём объект стандартного класса и помещаем в него данные о пользователе из БД. Далее в коде, когда получим данные о пользователе из социалки, проверим данные два объекта на равенство и если они не равны, то обновим запись в базе.

if (!$record) {
...
else {
    $userFromDb = new stdClass();
    $userFromDb->provider   = $record;
    $userFromDb->socialId   = $record;
    $userFromDb->name       = $record;
    $userFromDb->email      = $record;
    $userFromDb->socialPage = $record;
    $userFromDb->sex        = $record;
    $userFromDb->birthday   = date('m.d.Y', strtotime($record));
    $userFromDb->avatar     = $record;
}
...
$user; // в переменной $user записываем данные из социалки

// проверяем на равенство объект с данными из БД и объект с данными из социалки
if (isset($userFromDb) && $userFromDb != $user) {
    $idToUpdate = $record;
    $birthday = date('Y-m-d', strtotime($user->birthday));

    mysql_query(
        "UPDATE `users` SET " .
        "`social_id` = '{$user->socialId}', `name` = '{$user->name}', `email` = '{$user->email}', " .
        "`social_page` = '{$user->socialPage}', `sex` = '{$user->sex}', " .
        "`birthday` = '{$birthday}', `avatar` = '$user->avatar' " .
        "WHERE `id`='{$idToUpdate}'"
    );
}

Создаём новое приложение «ВКонтакте»

Перед тем, как писать код, нам нужно зарегистрировать новое приложение. Делается это просто, заходим в свой профиль, переходим в раздел приложения и в нем кликаем на кнопку «Управление». В этом разделе вы увидите список всех приложений, которыми вы пользуетесь и кнопку «Создать приложение», жмём по ней. Заполняем название и выбираем пункт «Веб-сайт».

После этого появятся два новых поля, которые также заполняем и жмём «Подключить сайт». В следующем окне вам останется подтвердить регистрацию.

Вот так просто и быстро регистрируется новое приложение «ВКонтакте». Теперь переходим в настройки и копируем ID приложения и защищенный ключ в блокнот. На этом работа с социальной сетью заканчивается.

Делаем авторизацию через ВК:

Теперь посмотрим как делается сама авторизация через ВК на PHP, для этого, сначала нужно создать кнопку, которая будет отсылать во ВК, но перед этим сделаем файл config.php, в котором будим хранить нужные нам данные.

PHP

1 2 3 4 5 6

// Константа для ID приложения

define(‘ID’,’ID приложения’);

// Константа для Защищённый ключа

define(‘SECRET’,’Защищённый ключ’);

// Константа для Доверенный redirect URI

define(‘URL’,’Доверенный redirect URI’);

В этом файле просто хранятся константы нужных данных нашего приложения.

Теперь создаём страницу авторизации, вот она.

PHP

1 2 3 4 5

<?php // Подключаем config

require_once’config.php’;

?>

<ahref=»https://oauth.vk.com/authorize?client_id=<?= ID ?>&redirect_uri=<?= URL ?>&display=page»>ВойтичерезВК<a>

Тут просто подключаем файл «config.php» и создаём ссылку для входа через ВКонтакте.

Потом когда мы перейдём где будем обрабатывать основную авторизацию, у нас будет GET запрос, но об этом позже.

Также есть ещё два значения в запросе, это в нём передаём ID приложения, а второй это , тут указывается тип страницы для авторизации, у нас это , которая используется для обычных WEB сайтов.

Примечание:

Если вам не понятна работа с GET запросами и вообще с формой, то посмотрите эту часть нашего учебника по PHP:  PHP работа с формой.


Вот как у нас выглядит страница.

Теперь перейдём к обработчику авторизации и получению данных пользователя.

PHP

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

// Подключаем файл config.php

require_once»config.php»;

  // Проверка, на то, что есть значение code в GET запросе

if(!$_GET»code»){

// Если нет, то прерываем программу и выводим надпись

exit(«Что то пошло не так»);

}else{// Иначе

// Создаём URL для запрса

$url=»https://oauth.vk.com/access_token?client_id=».ID.»&client_secret=».SECRET.»&redirect_uri=».URL.»&code=».$_GET»code»;

// Получаем токен с помощью запроса

$token=json_decode(file_get_contents($url),true);

if(!$token){// Если токена нет то

// Прерываем программу и выводим надпись

exit(«Что то пошло не так с токинам»);

}else{// Иначе

// Создаём URL нового запроса

$url=»https://api.vk.com/method/users.get?v=5.21&user_id=».$token’user_id’.»&c=».$token»access_token».»&fields=uid,first_name,last_name»;

// Делаем запрос и получаем данные

$data=json_decode(file_get_contents($url),true);

// Выводим данные

echo»<pre>»;

var_dump($data);

echo»</pre>»;

}

}

Тут уже всё сложнее, сперва мы проверяем, есть ли вообще код, для последующей работе с авторизацией, если нет, то прерываем программу, если да, то делаем URL запрос.

В этом GET запросе можете заметить несколько значений два из них знакомы, о них можете ознакомится выше, остальные сейчас разберём.

Первый, , это наш защищённый ключ, второе значение код который у нас есть из GET запроса.

После этого мы отправляем GET запрос с помощью функции , в качестве ответа, она вернёт JSON массив, который не читается PHP, поэтому мы объявляем функцию внутри другой функции , которая декодирует формат JSON, в качестве второго параметр она принимает , что означает декодирование в обычный ассоциативный массив PHP, это массив присваиваем переменной .

После чего опять проверяем, имеет ли значение переменная , если нет, то останавливаем программу и выводим сообщение, если да то опять делаем URL запрос.

Как можете заметить, значение которые мы отправляем, они все взяты из массива ,  первое значение тут отправляем ID пользователя, второй , это токиен аутентификации, третье значение, , это какие данные пользователя мы хотим получить, в нашем случае, хотим получить id пользователя и его имя, фамилию.

Важно:

Также очень важное значение , без него вообще не чего работать не будит, он указывает версию API. После, точно так же, как и прошлый раз, отправляем этот запрос, получаем массив и выводим его, вот что должно получится

После, точно так же, как и прошлый раз, отправляем этот запрос, получаем массив и выводим его, вот что должно получится.

Теперь авторизация ВКонтакте на PHP готов. Как видите всё работает как надо, теперь вам просто нужно полученные данные отправить в базу данных или например в cookie.

Если не знаете как работать с базой данных, то посмотрите наш учебник про работу с базой данных в PHP.

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

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

В первую очередь, снова сформируем параметры для этого запроса. Нам потребуется передать параметры: `code` — url параметр, пришедший от одноклассников; `redirect_uri` — страница, на которую будет возвращён пользователь; `grand_type`, равный значению «authorization_code» — код активации; `client_id` — id приложения; `client_secret` — секретный ключ:

if (isset($_GET)) {
    $params = array(
        'code' => $_GET,
        'redirect_uri' => $redirect_uri,
        'grant_type' => 'authorization_code',
        'client_id' => $client_id,
        'client_secret' => $client_secret
    );

    $url = 'http://api.odnoklassniki.ru/oauth/token.do';
}

Далее нам нужно отправить POST запрос на адрес http://api.odnoklassniki.ru/oauth/token.do, передав перечисленные параметры. В PHP выполнить POST запрос можно с помощью создания curl запроса:

if (isset($_GET)) {
    $params = array(
        'code' => $_GET,
        'redirect_uri' => $redirect_uri,
        'grant_type' => 'authorization_code',
        'client_id' => $client_id,
        'client_secret' => $client_secret
    );

    $url = 'http://api.odnoklassniki.ru/oauth/token.do';
    
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url); // url, куда будет отправлен запрос
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, urldecode(http_build_query($params))); // передаём параметры
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    $result = curl_exec($curl);
    curl_close($curl);

    $tokenInfo = json_decode($result, true);
}

В результате, при успешном выполнении запроса, в переменную $tokenInfo будет записан ответ от Одноклассников в JSON формате. Данная строка содержит 3 параметра: token_session — тип токена; refresh token — маркер обновления информации, access_token, который мы будем использовать в следующих запросах для извлечения информации о пользователе.

{"token_type":"session","refresh_token":"70309a1a6a10f8ced803c6d601d88fbaa8c6e_208576168129_1363174","access_token":"0.ipa2a6002o2f3y6sr703k70bsrva7-164"}

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

Фаза обратного вызова Callback OAuth

Поставщик OAuth перенаправляет обратно в приложение после аутентификации пользователя и дает разрешение на обмен информацией. Маршрут, который обрабатывает этот обратный вызов, показан ниже:

Этот маршрут создает экземпляр класса поставщика и вызывает его метод . Этот метод имеет функцию завершения аутентификации с провайдером и получения информации о пользователе. Возвращаемое значение представляет собой кортеж с тремя значениями, уникальный идентификатор (называемый , чтобы отличать его от первичного ключа ), псевдоним пользователя и адрес электронной почты пользователя. Идентификатор и псевдоним являются обязательными, но в этом примере приложения я сделал электронное письмо необязательным, так как Twitter никогда не делится этой информацией с приложениями.

Пользователь просматривается в базе данных по полю , и если не найден, новый пользователь добавляется в базу данных с информацией, полученной от провайдера, эффективно регистрируя новых пользователей автоматически. Затем пользователь регистрируется с помощью функции в Flask-Login и, наконец, перенаправляется на домашнюю страницу.

Реализация метода для провайдеров OAuth для Facebook и Twitter показана ниже:

В методе передается токен проверки, который приложение может использовать для связи с API-интерфейсом провайдера. В случае OAuth 2 это происходит как аргумент , тогда как для OAuth 1.0a это , оба заданные в строке запроса. Этот код используется для получения из объекта службы rauth.

Обратите внимание, что в последних версиях API Facebook токен сеанса возвращается в формате JSON. Формат по умолчанию, ожидаемый rauth для этого токена, должен указываться в строке запроса

По этой причине, необходимо добавить аргумент , который декодирует содержимое JSON. В Python 2 достаточно передать , но в Python 3 нам нужен дополнительный шаг, потому что полезная нагрузка возвращается как байты, которые json-парсер не понимает. Преобразование из байтов в строку выполняется во внутренней функции decode_json.

Объект может использоваться для предоставления API-запросов поставщику. Здесь он используется для запроса информации о пользователе, которая должна предоставляться определенным провайдером. Facebook предоставляет идентификатор пользователя и адрес электронной почты, но не дает имен пользователей, поэтому имя пользователя для приложения создается из левой части адреса электронной почты. Twitter предоставляет идентификатор и имя пользователя, но не поддерживает электронную почту, поэтому электронное письмо возвращается как .


Данные, полученные от провайдера, окончательно возвращаются в виде трехэлементного кортежа для функции просмотра

Обратите внимание, что в обоих случаях значение от провайдера добавляется с или до его возврата, чтобы сделать его уникальным для всех поставщиков. Поскольку это то, что приложение будет хранить как в базе данных, необходимо сделать это, чтобы два поставщика, которые назначили один и тот же двум различным пользователям, не конфликтовали в базе данных приложения

Что и как

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

Первым делом нужно авторизовать пользователя, поэтому нужно перенаправить его на сайт ВКонтакте. Добавляем метод в имеющийся класс:

В поле scope передаются запрашиваемые права доступа приложения. Для считывания основной информации достаточно offline. Но если нужно большее, то их можно перечислять через запятую:

Небольшое пояснение: redirect() — это метод, реализующий перенаправление. Для удобства в этом примере он вынесен в класс Utils

После авторизации и подтверждения доступа пользователь переадресовывается на адрес URL_CALLBACK?code=xxx. Теперь нужно по переданному нам коду взять токен и запросить данные пользователя. Если же пользователь отклонил запрос или возникла ошибка, то он перенаправится на адрес URL_CALLBACK с кодом и описанием ошибки, например URL_CALLBACK?error=invalid_request&error_description=Invalid+display+parameter.

То есть, логику можно разместить в эти условия:

Запросить токен:

Объект $res при удачном запросе будет содержать такие поля:

Expires_in — это время жизни токена в секундах, оно может понадобится только при длительных запросах на сервер, а по остальным ключам и так понятно что здесь что. Далее, если используете OAuth для полноценной регистрации, логично сделать проверку зарегистрирован ли на сайте кто-либо с таким user_id и при наличии оного авторизовать его и перекинуть на главную страницу сайта (или любую другую), исключив последующие действия.

Далее по токену и user_id остается запросить данные пользователя. Все запросы к API ВКонтакте выполняются по такому адресу:https://api.vk.com/method/METHOD_NAME?PARAMETERS&access_token=ACCESS_TOKEN

METHOD_NAME – название метода из списка функций APIPARAMETERS – параметры соответствующего метода APIACCESS_TOKEN – ключ доступа, полученный в результате успешной авторизации приложения

Ответ приходит в формате JSON. Если же вы более привыкли в XML, то либо привыкайте к JSON, либо отсылайте запросы на такой адрес:https://api.vk.com/method/METHOD_NAME.xml?PARAMETERS&access_token=ACCESS_TOKEN

Запрос данных пользователей по их user_id осуществляется через метод getProfiles или его полный аналог users.get. При необходимости можно также отправлять параметр fields и получать дополнительные данные пользователя.

В нашем примере ответ от сервера приходит в таком виде (в зависимости от параметров количество полей может быть больше):

Имя, фамилия и uid пользователя теперь известны нам, что делать с ними дальше — решайте сами. Я использую OAuth для полноценной регистрации и создаю с этими данными нового пользователя на сайте.

Дополнительно:

  • Скачать получившийся класс OAuth авторизации
  • Официальная документация ВКонтакте API
  • Создание приложения ВКонтакте
  • Управление приложениями ВКонтакте

License

(The MIT License)

Copyright (c) 2011 Jared Hanson

Copyright (c) 2012, 2016 Stepan Stolyarov

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the «Software»), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED «AS IS», WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

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

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

$url = 'http://oauth.vk.com/authorize';

$params = array(
    'client_id'     => $client_id,
    'redirect_uri'  => $redirect_uri,
    'response_type' => 'code'
);

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

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

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

http://oauth.vk.com/authorize?client_id=3485070&redirect_uri=http%3A%2F%2Flocalhost%2Fvk-auth&response_type=code

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

http://oauth.vk.com/authorize?client_id=3485070&redirect_uri=http://localhost/vk-auth&response_type=code
// Пример. В вашем случае код будет другой
http://localhost/vk-auth/?code=f30621b146115b3bad

С этим читают