
Представляем yet another PHP-пакет интеграции с ЕСИА — ekapusta/oauth2-esia. Реализован как адаптер к популярному league/oauth2-client.
Оргмоменты
Интеграция с ЕСИА затрагивает госорганы, финансовые и страховые компании, кредитные организации (банки, микрофинансы), организации с публичным wi-fi'ем и прочих, кому в будущем правительство даст добро. Основные оргмоменты описаны на Хабре по запросу "ЕСИА", актуальные версии документов доступны на оф. сайте, а поддержку можно получить в относительно разумные сроки через esia@minsvyaz.ru.
Почему этот пакет?
- Получение основных и вложенных данных гражданина делается в один запрос, используя доступные в ЕСИА
embeds. Т.е. для получения контактов/адресов не надо будет делать ещё N отдельных запросов. - Два варианта подписи запроса: через CLI и через встроенные PHP-функции. Что позволяет работать по RSA и по GOST'у. CLI подписывателю не нужна временная директория.
- Подпись токена доступа проверяется публичными ключами ЕСИА.
- Основан на покрытом тестами
league/oauth2-client, к которому является адаптером, не изобретая велосипеды и сам покрыт тестами на 100%. - В тестах есть элементы интеграции — аутентификационный бот, который ходит в реальный тестовый стенд. Спасибо headless-chrome'у.
- Генерация стейта и разбор JWT токена использует пакеты, специально для этого написанные:
ramsey/uuidиlcobucci/jwt. - Совместим с PHP
^ 5.6 || ^ 7.0.
Покажите код!
Конфигурируем
use Ekapusta\OAuth2Esia\Provider\EsiaProvider; use Ekapusta\OAuth2Esia\Security\Signer\OpensslPkcs7; $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 -i -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
Благодарим за внимание
Пакет заоперсорсен финтех-компанией в которой я работаю. Не тестировалось на животных.
UPD1
Бонусом идёт symfony-бандл ekapusta/oauth2-esia-bundle:
- php:
^5.6 || ^7.0 - symfony:
^2.8 || ^3 || ^4.
