Создать свой API

В этой статье мы рассмотрим, что нужно, чтобы создать свой собственный three-legged OAuth server. Он позволит вам создать, например, свой собственный безопасный API, который можно распространить.

Оглавление:
  1. Создать API
  2. Понимание потока
  3. Настройка базы данных
  4. Создание сервера OAuth
  5. Разрешение регистрации
  6. Создание маркера запроса
  7. Замена маркера запроса на маркер доступа
  8. Проверка запроса
  9. Тестирование сервера OAuth
  10. Заключение

Когда работаешь с OAuth он как правило реализован на two-legged (двуногие) или three-legged (трёхногие) OAuth server. Основное различие между ними заключается в том, что на двуногих аутентификация не связана с другим пользователем. Например, если вы хотите получить доступ к информации определенного пользователя Twitter, вам нужно использовать трёхногие сервера, так как маркер доступа должен быть получен для пользователя в вашем ззапросе, по сравнению с Twitter который просто предоставляет вам маркер. Мы рассмотрим three-legged, поскольку он на и более чаще используется.

Создать API

Выполнять тяжелую работу для нас мы заставим OAuth-PHP. Библиотека размещается на Google Code, и не перечислена в Packagist, но можно установить с помощью композитора. Для получения дополнительной информации, смотрите файл composer.json.

к меню ↑

Понимание потока

При использовании three-legged OAuth server, типичный поток, который нам потребуется для реализации и потребления услуг, выглядит следующим образом:

Типичный поток, который разработчикам потребуется для реализации и потребления услуг
Типичный поток, который разработчикам потребуется для реализации и потребления услуг

Рисунок OAuth.net, является довольно сложным, если разобраться там показано следующее:

  • Потребительские запросы маркера с сервера
  • Затем потребитель направляет пользователя на страницу входа, передавая с ним маркер
  • Пользователь входит в систему и перенаправляется обратно к потребителю маркера доступа
  • Потребитель берет маркер доступа и просит ключ OAuth для использования в будущих безопасных запросах
  • Маркера OAuth извлекается, и разработчик может теперь сделать безопасные запросы передачи маркера для проверки
к меню ↑

Настройка базы данных

С библиотекой OAuth PHP в доступном месте, новая база данных должна быть создана и инициализирована. Используем схему сценария поиска в library/store/mysql/mysql.sql.

Если вы просмотрели таблицу, значить видели, что таблица oauth_server_registry содержит поле с именем osr_usa_id_ref. Заполняется в процессе регистрации на сервере OAuth. И предполагает, что вы уже существующий пользователь, и будет иметь отношение к таблице. Если вы это делаете, это здорово! А если нет, то вот некоторые основные SQL запросы, чтобы создать стандартного пользователя:

CREATE TABLE users (
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL DEFAULT '',
password VARCHAR(255) NOT NULL DEFAULT '',
email VARCHAR(255) NOT NULL DEFAULT '',
created DATE NOT NULL DEFAULT '0000-00-00',

PRIMARY KEY (id)
);
к меню ↑

Создание сервера OAuth

Давайте начнем писать OAuth-сервер. Следующий код является общим для остальной части нашего кода, поэтому я поместил его в отдельный файл, include/common.php:

<?php
require_once '../vendor/autoload.php';

session_start();

// Add a header indicating this is an OAuth server
header('X-XRDS-Location: http://' . $_SERVER['SERVER_NAME'] .
'/services.xrds.php');

// Connect to database
$db = new PDO('mysql:host=localhost;dbname=oauth', 'dbuser', 'dbpassword');

// Create a new instance of OAuthStore and OAuthServer
$store = OAuthStore::instance('PDO', array('conn' => $db));
$server = new OAuthServer();

Файл добавляет дополнительный заголовок HTTP для каждого запроса информирует клиентов что это OAuth-сервер. Обратите внимание, ссылки services.xrds.php; этот файл с примером, который приходит с библиотекой OAuth PHP. Вы должны скопировать его из example/server/www/services.xrds.php в корневой каталог общего веб-сервера.

Следующие несколько строк кода устанавливают подключения к базе данных (информация о соединении, должна быть обновлена соответственно с вашим собственными настройками) и создаст новые экземпляры объектов OAuthStore и OAuthServer, предусмотренных в библиотеке.

Настройка для OAuth сервера завершена, и сервер готов полностью к применению. В остальных примерах, includes/common.php файл должен быть включен каждый раз для создания экземпляра сервера.

к меню ↑

Разрешение регистрации

Прежде чем использовать сервер OAuth нужно зарегистрироваться. Для этого нам необходимо создать простую форму регистрации. Следующие поля необходимы, потому что они передают в библиотеку: requester_name и requester_email. Остальные поля являются необязательными: application_uri и callback_uri.

<form action="register.php" method="post">
<fieldset><legend>Регистрация</legend>
<div><label for="requester_name">Логин</label>
<input id="requester_name" type="text" name="requester_name" /></div>
<div><label for="requester_email">Email</label>
<input id="requester_email" type="text" name="requester_email" /></div>
<div><label for="application_uri">URI</label>
<input id="application_uri" type="text" name="application_uri" /></div>
<div><label for="callback_uri">Обратный URI</label>
<input id="callback_uri" type="text" name="callback_uri" /></div></fieldset>
<input type="submit" value="Зарегистрировать" /></form>

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

<?php
$stmt = $db->prepare('INSERT INTO users (name, email, created) ' .
'VALUES (:name, :email, NOW())');
$stmt->execute(array(
'name' => $_POST['requester_name'],
'email' => $_POST['requester_email']
));
$id = $db->lastInsertId();

$key = $store->updateConsumer($_POST, $id, true);
$c = $store->getConsumer($key, $id);
?>
<p><strong>Сохранить свойства!</strong></p>
<p>Потребительский ключ: <strong><?=$c['consumer_key']; ?></strong></p>
<p>Потребительский секрет: <strong><?=$c['consumer_secret']; ?></strong></p>

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

После того как пользователь зарегистрирован он может начинать делать запросы маркеру доступа!

к меню ↑

Создание маркера запроса

После того как пользователь зарегистрирован, он должен выполнить OAuth запрос к вашему файлу request_token.php.

Этот файл предельно прост:

<?php
require_once 'include/oauth.php';

$server->requestToken();

Метод RequestToken() заботится о предоставлении пользователем действительного ключа и подпись. Если запрос действителен, новый маркер запроса возвращается.

к меню ↑

Замена маркера запроса на маркер доступа

Пользователь должен быть перенаправлен на страницу входа. Чтобы был только один раз сформирован маркер запроса нужны следующие параметры URL:oauth_token и oauth_callback.

Страница входа должна получить пользователя из таблицы пользователей. Как только он определён, идентификатор пользователя передается (наряду с oauth_token) в метод authorizeVerify(), предусмотренный в библиотеке.

Необходимая логика login.php может выглядеть следующим образом:

<?php
// check if the login information is valid and get the user's ID
$sql = 'SELECT id FROM users WHERE email = :email';
$stmt = $db->prepare($sql);
$result = $stmt->exec(array(
'email' => $_POST['requester_email']
));
$row = $result->fetch(PDO::FETCH_ASSOC);

if (!$row) {
// incorrect login
}
$id = $row['id'];
$result->closeCursor();

// Check if there is a valid request token in the current request.
// This returns an array with the consumer key, consumer secret,
// token, token secret, and token type.
$rs = $server->authorizeVerify();
// See if the user clicked the 'allow' submit button (or whatever
// you choose)
$authorized = array_key_exists('allow', $_POST);
// Set the request token to be authorized or not authorized
// When there was a oauth_callback then this will redirect to
// the consumer
$server->authorizeFinish($authorized, $id);

После того как пользователь войдет в систему, он будут перенаправлен обратно на веб-сайт (через параметр oauth_callback) с действительным маркером. Ключ может быть использован в обмен на действительный маркер доступа.

Основной файл access_token.php выглядит следующим образом:

<?php
require_once 'include/oauth.php';

$server->accessToken();

Этот файл также прост как и ранее созданный request_token.php. Работа делается внутри метода accessToken(), предусмотренный библиотекой OAuth PHP. После успешного запроса выводятся действительные oauth_token и oauth_token_secret, которые должны быть сохранены и использованы при последующих запросах к вашему API.

к меню ↑

Проверка запроса

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

<?php
require_once 'includes/oauth.php';

if (OAuthRequestVerifier::requestIsSigned()) {
try {
$req = new OAuthRequestVerifier();
$id = $req->verify();
// If we have a user ID, then login as that user (for
// this request)
if ($id) {
echo 'Hello ' . $id;
}
} catch (OAuthException $e) {
// The request was signed, but failed verification
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: OAuth realm=""');
header('Content-Type: text/plain; charset=utf8');
echo $e->getMessage();
exit();
}
}

Если запрос подтвержден, просто повторите идентификатор пользователя из пользователей которые вошли. Можно создать повторно используя эти методы, которые содержат этот код на любые вызовы API для безопасности.

к меню ↑

Тестирование сервера OAuth

Наконец, пришло время для проверки OAuth-сервера. Ниже приведен простой тестовый файл, который выполняет вышеуказанные действия:

<?php
define('OAUTH_HOST', 'http://' . $_SERVER['SERVER_NAME']);
$id = 1;

// Init the OAuthStore
$options = array(
'consumer_key' => '<MYCONSUMERKEY>',
'consumer_secret' => '<MYCONSUMERSECRET>',
'server_uri' => OAUTH_HOST,
'request_token_uri' => OAUTH_HOST . '/request_token.php',
'authorize_uri' => OAUTH_HOST . '/login.php',
'access_token_uri' => OAUTH_HOST . '/access_token.php'
);
OAuthStore::instance('Session', $options);

if (empty($_GET['oauth_token'])) {
// get a request token
$tokenResultParams = OauthRequester::requestRequestToken($options['consumer_key'], $id);

header('Location: ' . $options['authorize_uri'] .
'?oauth_token=' . $tokenResultParams['token'] .
'&oauth_callback=' . urlencode('http://' .
$_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF']));
}
else {
// get an access token
$oauthToken = $_GET['oauth_token'];
$tokenResultParams = $_GET;
OAuthRequester::requestAccessToken($options['consumer_key'],
$tokenResultParams['oauth_token'], $id, 'POST', $_GET);
$request = new OAuthRequester(OAUTH_HOST . '/test_request.php',
'GET', $tokenResultParams);
$result = $request->doRequest(0);
if ($result['code'] == 200) {
var_dump($result['body']);
}
else {
echo 'Error';
}
}

OAuth требуются метки и подписи которые должны были быть приложены к каждому запросу, это выполняет библиотека.

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

Как описано в three-legged OAuth server, следующий процесс выполняется в приведенном выше тестовом файле:

  • Запрос маркера (через файл request_token.php) с потребительским ключом
  • Получив маркер, перенаправить пользователя на страницу входа передачей маркера и обратного вызова URL через параметры URL
  • После того как пользователь вошел в систему, он будут перенаправлен обратно на страницу теста. На тестовой странице принимает маркер и просит маркер доступа (через файл access_token.php)
  • В случае успеха, необходимая информация OAuth возвращается и тестовый файл выполняет безопасный запрос test_request.php.
  • Если все пойдет хорошо слово «Hello» будет отображаться.
к меню ↑

Заключение

Вы должны знать как создать базовый сервер OAuth с использованием файла test_request.php. Например, вы можете начать создавать закрепленные OAuth! Если вы хотите поиграться с кодом, смотрите полный исходный код для этой статьи. И рекомендую посмотреть пример работы OAuth.

,
htmlhook.ru | Скрипты для веб-приложений