Интеграция с ЕСИА на базе oauth2-client (PHP)

в 3:11, , рубрики: oauth2, open source, OpenConnect, php, php5, php7, госуслуги, есиа, финтех

Интеграция с ЕСИА на базе oauth2-client (PHP) - 1

Представляем yet another PHP-пакет интеграции с ЕСИА — ekapusta/oauth2-esia. Реализован как адаптер к популярному league/oauth2-client.

Оргмоменты

Интеграция с ЕСИА затрагивает госорганы, финансовые и страховые компании, кредитные организации (банки, микрофинансы), организации с публичным wi-fi'ем и прочих, кому в будущем правительство даст добро. Основные оргмоменты описаны на хабре по запросу "ЕСИА", актуальные версии документов доступны на оф. сайте http://minsvyaz.ru/ru/documents/?directions=13, а поддержку можно получить в относительно разумные сроки через esia@minsvyaz.ru.

Почему этот пакет?

Build Status Coverage Status Software License Интеграция с ЕСИА на базе oauth2-client (PHP) - 5

  • Получение основных и вложенных данных гражданина делается в один запрос, используя доступные в ЕСИА embeds. Т.е. для получения контактов/адресов не надо будет делать ещё N отдельных запросов.
  • Два варианта подписи запроса: через CLI и через встроенные PHP-функции. Что позволяет работать по RSA и по GOST'у. CLI подписывателю не нужна временная директория.
  • Подпись токена доступа проверяется публичными ключами ЕСИА.
  • Основан на покрытом тестами league/oauth2-client, к которому является адаптером, не изобретая велосипеды и сам покрыт тестами на 100%.
  • В тестах есть элементы интеграции — аутентификационный бот, который ходит в реальный тестовый стенд. Спасибо headless-chrome'у.
  • Генерация стейта и разбор JWT токена использует пакеты, специально для этого написанные: ramsey/uuid и lcobucci/jwt.
  • Совместим с PHP ^ 5.6 || ^ 7.0.

Покажите код!

Конфигурируем

use EkapustaOAuth2EsiaProviderEsiaProvider;
use EkapustaOAuth2EsiaSecuritySignerOpensslPkcs7;

$provider = new EsiaProvider([
    'clientId'      => 'XXXXXX', // "Мненомика" в терминах ЕСИА
    'redirectUri'   => 'https://your-system.domain/auth/finish/',
    'defaultScopes' => ['openid', 'fullname', '...'], // Скоупы описаны в методичке
// Для работы с тестовой версией портала
//  'remoteUrl' => 'https://esia-portal1.test.gosuslugi.ru',
//  'remoteCertificatePath' => EsiaProvider::RESOURCES.'esia.test.cer',
], [
    'signer' => new OpensslPkcs7('/path/to/public/certificate.cer', '/path/to/private.key')
]);

Какой подписыватель использовать?

  • Если вы используете ключи RSA, достаточно OpensslPkcs7.
  • Если вы используете ключи GOST и скомпилировали PHP с шифрами ГОСТ, то достаточно OpensslPkcs7.
  • Если вы используете ключи GOST и имеете инструмент, совместимый с openssl, используйте OpensslCli. Он имеет параметр «toolpath».
  • Если вы используете ключи GOST и фанат докера, вы можете использовать OpensslCli с параметром 'toolpath' => 'docker run -rm -v $(pwd):$(pwd) -w $(pwd) rnix/openssl-gost openssl'.

Редиректим посетителя на ЕСИА

Одновременно сохраняя стейт для последующей проверки.

// Где-то страничке https://your-system.domain/auth/start/
$authUrl = $provider->getAuthorizationUrl();
$_SESSION['oauth2.esia.state'] = $provider->getState();
header('Location: '.$authUrl);
exit;

Получаем данные пользователя

Проверяя стейт и меняя код на аутентификационный токен.

// Где-то страничке https://your-system.domain/auth/finish/?state=...&code=...
if ($_SESSION['oauth2.esia.state'] !== $_GET['state']) {
    exit('The guard unravels the crossword.');
}

$token = $provider->getAccessToken('authorization_code', ['code' => $_GET['code']]);
$esiaPersonData = $provider->getResourceOwner($accessToken);
var_export($esiaPersonData->toArray());

Как обновить токен?

Стандартно, как описано в документации к oauth2-client: https://github.com/thephpleague/oauth2-client#refreshing-a-token

Благодарим за внимание

Пакет заоперсорсен финтех-компанией в которой я работаю. Не тестировалось на животных.

Автор: garex

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js