Аутентификация через Одноклассники

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

Если кто пропустил предыдущую часть, то её можно найти тут:

sourse

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

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

Для работы примера вам нужно будет самим зарегистрировать новое приложение и ввести собственные параметры. Для начала нам необходимо создать новое приложение на сайте социальной сети Одноклассники

На открывшейся странице выбираем вид приложения: “Вне Одноклассников”; тип приложения: "oAuth авторизация".

После этого нам необходимо заполнить следующую форму:

Название будет "Odnoklassniki Auth". Shortname - это тоже название приложения, но только то, что будет отображаться в url адресе: "ondoklassniki-oauth". Ссылка на приложение: http://localhost/odnoklassniki-auth. Таким образом, на локальном сервере нам потребуется создать папку "odnoklassniki-auth" и поместить все рабочие файлы туда.

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

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

<?php

$client_id = '104639696'; // Application ID
$public_key = 'CBAJLKABACMBABABA'; // Публичный ключ приложения
$client_secret = '734D4692BA61A3E96F88B62D'; // Секретный ключ приложения
$redirect_uri = 'http://localhost/odnoklassniki-auth'; // Ссылка на приложение

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

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

$url = 'http://www.odnoklassniki.ru/oauth/authorize';
$params = array(
    'client_id'     => $client_id,
    'response_type' => 'code',
    'redirect_uri'  => $redirect_uri
);

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

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

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

http://www.odnoklassniki.ru/oauth/authorize?client_id=104639696&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%2Fodnoklassniki-auth

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

http://www.odnoklassniki.ru/oauth/authorize?client_id=104639696&response_type=code&redirect_uri=http://localhost/odnoklassniki-auth

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

// Пример. В вашем случае, код будет другой
http://localhost/odnoklassniki-auth/?code=d7820742ac21d6206d50884b7fa6544fcafdf491029c301cfd.ebf2f661_037c622e17112e245698f29705c5c41b_1363169481

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

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

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

if (isset($_GET['code'])) {
    $params = array(
        'code' => $_GET['code'],
        '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['code'])) {
    $params = array(
        'code' => $_GET['code'],
        '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.

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

Итак, теперь когда у нас есть параметры access_token, мы можем сделать запрос к Одноклассники API и получить информацию о пользователе. Перед тем, как мы подготовим массив с параметрами, которые в последствии превратим в фрагмент url строки, нам нужно сформировать специальную `подпись` запроса $sign с помощью конкатенации двух хэшей md5;

if (isset($tokenInfo['access_token']) && isset($public_key)) {
    $sign = md5("application_key={$public_key}format=jsonmethod=users.getCurrentUser" . md5("{$tokenInfo['access_token']}{$client_secret}"));

    $params = array(
        'method'          => 'users.getCurrentUser',
        'access_token'    => $tokenInfo['access_token'],
        'application_key' => $public_key,
        'format'          => 'json',
        'sig'             => $sign
    );
}

В параметр method записываем название метода API Одноклассников, который вернёт нам информацию о пользователе; Далее передаём access_token, публичный ключ (application_key), формат возвращаемых данных (format) и подпись запроса (sig).

Для получения информации о пользователе сформированные параметры нам нужно отправить GET запросом по адресу http://api.odnoklassniki.ru/fb.do:

if (isset($tokenInfo['access_token']) && isset($public_key)) {
    $sign = md5("application_key={$public_key}format=jsonmethod=users.getCurrentUser" . md5("{$tokenInfo['access_token']}{$client_secret}"));

    $params = array(
        'method'          => 'users.getCurrentUser',
        'access_token'    => $tokenInfo['access_token'],
        'application_key' => $public_key,
        'format'          => 'json',
        'sig'             => $sign
    );

    $userInfo = json_decode(file_get_contents('http://api.odnoklassniki.ru/fb.do' . '?' . urldecode(http_build_query($params))), true);
}

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

"uid":"208576168129","birthday":"1988-07-03","age":24,"first_name":"Станислав","last_name":"Протасевич","name":"Станислав Протасевич","locale":"ru","gender":"male","has_email":true,"location":{"country":"MOLDOVA,_REPUBLIC_OF","city":"Кишинёв"},"current_status":"Очередная гениальная идея! Вперёд!","current_status_id":"553191546561","current_status_date":"2012-11-14 23:58:50","online":"web","pic_1":"http://i512.odnoklassniki.ru/getImage?photoId=443580540097&photoType=4","pic_2":"http://usd13.odnoklassniki.ru/getImage?photoId=443580540097&photoType=2"

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

if (isset($tokenInfo['access_token']) && isset($public_key)) {
    $sign = md5("application_key={$public_key}format=jsonmethod=users.getCurrentUser" . md5("{$tokenInfo['access_token']}{$client_secret}"));

    $params = array(
        'method'          => 'users.getCurrentUser',
        'access_token'    => $tokenInfo['access_token'],
        'application_key' => $public_key,
        'format'          => 'json',
        'sig'             => $sign
    );

    $userInfo = json_decode(file_get_contents('http://api.odnoklassniki.ru/fb.do' . '?' . urldecode(http_build_query($params))), true);
    
    if (isset($userInfo['uid'])) {
        $result = true;
    }
}

Полный код:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
    <title></title>
</head>
<body>
<?php

$client_id = '104639696'; // Application ID
$public_key = 'CBAJLKABACMBABABA'; // Публичный ключ приложения
$client_secret = '734D4692BA61A3E96F88B62D'; // Секретный ключ приложения
$redirect_uri = 'http://localhost/odnoklassniki-auth'; // Ссылка на приложение

$url = 'http://www.odnoklassniki.ru/oauth/authorize';

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

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

if (isset($_GET['code'])) {
    $result = false;

    $params = array(
        'code' => $_GET['code'],
        '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);
    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);

    if (isset($tokenInfo['access_token']) && isset($public_key)) {
        $sign = md5("application_key={$public_key}format=jsonmethod=users.getCurrentUser" . md5("{$tokenInfo['access_token']}{$client_secret}"));

        $params = array(
            'method'          => 'users.getCurrentUser',
            'access_token'    => $tokenInfo['access_token'],
            'application_key' => $public_key,
            'format'          => 'json',
            'sig'             => $sign
        );

        $userInfo = json_decode(file_get_contents('http://api.odnoklassniki.ru/fb.do' . '?' . urldecode(http_build_query($params))), true);
        if (isset($userInfo['uid'])) {
            $result = true;
        }
    }
}
?>
</body>
</html>

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

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

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

Шаг 6. И снова дело за вами

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

После этого, всё что нам осталось сделать, так это создать сессию и поместить в неё информацию о нашем пользователе.

$_SESSION['user'] = $userInfo;

На странице выхода из системы просто удаляем сессию с помощью функции unset.

Итог

Вот и всё. Теперь в вашей копилке на один рецепт больше, и вы можете порадовать ваших пользователей аутентификацией через социальную сеть "Одноклассники".

P.S. Отдельное спасибо хочу сказать всем, кто отписался в комментариях к предыдущей статье, ну и к этой тоже! В будущем буду стремиться учитывать ваши пожелания и предложения.

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: www.ruseller.com
Автор: Станислав Протасевич
Урок создан: 13 Марта 2013
Просмотров: 88633
Правила перепечатки


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

  • Фильтрация данных с помощью zend-filter

    Когда речь идёт о безопасности веб-сайта, то фраза "фильтруйте всё, экранируйте всё" всегда будет актуальна. Сегодня поговорим о фильтрации данных.

  • Контекстное экранирование с помощью zend-escaper

    Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.

  • Подключение Zend модулей к Expressive

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

  • Совет: отправка информации в Google Analytics через API

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

  • Подборка PHP песочниц

    Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.

^ Наверх ^