Esia-gosuslugi

Esia-gosuslugi pos gosuslugi

esia-gosuslugi

Модуль идентификации и авторизации пользователей через ЕСИА для Node.js с поддержкой ГОСТ 34.10

Перед использованием ознакомтесь с документацией.

использование

  1. Установите
  1. Создайте экземпляр подключения к ЕСИА
   
   

// читается сертификат используемый в ЕСИА
    
     

   
    : 
    : 
    : 'openid id_doc mobile fullname'
    : 
    : 
  1. Направьте пользвателя в ЕСИА для получения подтверждения

// сгенерируйте url для пользователя
 
  1. После того как пользователь авторизуется и даст разрешение на доступ к своим данным, он будет перенаправлен по адресу, указанному в redirectUri. Вы получите параметр code, который нужно будет использовать для запроса данных
 

Метод getAccess возвращает Promise, в который приходит объект результата. Этот объект содержит два поля:

  • marker – маркер доступа. Объект, содержащий поля:
    • response – объект, ответ от ЕСИА при запросе маркера
    • decodedAccessToken – объект, jwt декодированное значение поля access_token, содержащееся в response.
  • data – массив записей данных о пользователе.
  data       

// не будет запрошена информация о пользователе
  data     

Подробнее о получении информации о пользователе читайте в официальной документации ЕСИА.

  • Товара временно нет в наличии

    Модуль авторизации ЕСИА представляет собой набор файлов c исходным кодом. Имеются модификации на языках программирования PHP, C# (.Net), Java, Ruby, Python, а также готовые компоненты для CMS Bitrix (1С-Битрикс «Управление сайтом» и «Корпоративный портал»), WordPress, Drupal и Joomla.  Модуль  авторизации ЕСИА поддерживает биометрическую идентификацию и соответствует требованиями Методических рекомендаций единой биометрической системы (ЕБС) и Методическим рекомендациям по использованию Единой системы идентификации и аутентификации.

    Модуль реализует методы, необходимые для обеспечения процедур «Регламента информационного взаимодействия Участников с Оператором ЕСИА» и с учетом «Методических рекомендаций по использованию Единой системы идентификации и аутентификации». В частности, содержит методы для реализации следующих действий:

    • Формирования запроса на авторизацию к ЕСИА.
    • Получения и обработку ответа ЕСИА.
    • Проверки подписи ЕСИА.
    • Формирования запроса на отзыв авторизации (разлогин).
    • Принятия и обработки запроса на отзыв авторизации (разлогин со стороны ЕСИА).
    • Получения данных о пользователях в «офлайн» режиме (после того, как пользователь вышел из системы).
    • Получения данных о степени соответствия пользователя и его биометрического шаблона (биометрическая идентификация).
  • Основные характеристики

    Доставка и логистика

    • Срок доставки: 1-3 раб.дн. Softline.

    Информация на сайте ни при каких условиях не является публичной офертой, определяемой положениями статьи
    437(2) ГК РФ.
    Рекомендуем при покупке проверять наличие желаемых функций и характеристик. Описание, технические
    характеристики, комплектация
    и внешний вид продукта могут отличаться от заявленных или могут быть изменены производителем без
    предупреждения

  • Рассрочка от 8 200,43 ₽/мес

    Доставка 18 апреля или раньше

    Модуль авторизации ЕСИА представляет собой набор файлов c исходным кодом. Имеются модификации на языках программирования PHP, C# (.Net), Java, Ruby, Python, а также готовые компоненты для CMS Bitrix (1С-Битрикс «Управление сайтом» и «Корпоративный портал»), WordPress, Drupal и Joomla.  Модуль  авторизации ЕСИА поддерживает биометрическую идентификацию и соответствует требованиями Методических рекомендаций единой биометрической системы (ЕБС) и Методическим рекомендациям по использованию Единой системы идентификации и аутентификации.

    Модуль реализует методы, необходимые для обеспечения процедур «Регламента информационного взаимодействия Участников с Оператором ЕСИА» и с учетом «Методических рекомендаций по использованию Единой системы идентификации и аутентификации». В частности, содержит методы для реализации следующих действий:

    • Формирования запроса на авторизацию к ЕСИА.
    • Получения и обработку ответа ЕСИА.
    • Проверки подписи ЕСИА.
    • Формирования запроса на отзыв авторизации (разлогин).
    • Принятия и обработки запроса на отзыв авторизации (разлогин со стороны ЕСИА).
    • Получения данных о пользователях в «офлайн» режиме (после того, как пользователь вышел из системы).
    • Получения данных о степени соответствия пользователя и его биометрического шаблона (биометрическая идентификация).
  • Основные характеристики

    Доставка и логистика

    • Срок доставки: 1-3 раб.дн. Softline.

    Информация на сайте ни при каких условиях не является публичной офертой, определяемой положениями статьи
    437(2) ГК РФ.
    Рекомендуем при покупке проверять наличие желаемых функций и характеристик. Описание, технические
    характеристики, комплектация
    и внешний вид продукта могут отличаться от заявленных или могут быть изменены производителем без
    предупреждения

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

Общие для всех продуктов:
– Обновление продукта;
– Получение новых версий (можно посмотреть какие и как часто выходят обновления для Управления сайтом и для Битрикс24);
– Приоритетная техническая поддержка в первую очередь (срок ответа не превышает шести рабочих часов);
– Система резервного копирования в облако;
– Использование Маркетплейс
– Конструктор Сайты24

Уникальные для «1С-Битрикс: Управления сайтом»
– Обновление системы безопасности;
– Инспектор сайтов;
– Ускорение загрузки сайта CDN
– Мобильное приложение администратора магазина (для редакций «Малый бизнес» и «Бизнес»)
– Автобюджет контекста в Яндекс.Директ
– BigData: Персонализация
– Защита от DDoS

Уникальные для «1С-Битрикс24»
– Работа телефонии
– Автозаполнение реквизитов по ИНН
– Работа открытых линий:
  – настраивать и создавать Открытые линии можно без ограничений;
  – онлайн-чат работает без ограничений;
  – каналы коммуникаций исчезают из виджета CRM;
  – сообщения на портал из настроенных каналов продолжают приходить;
  – настроить каналы нельзя – будет выдаваться ошибка (кроме Онлайн-чата);
  – нельзя ответить на сообщения – они не доставляются.

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

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

После оплаты права использования программы, вы одновременно получаете две лицензии:

1. Стандартную – она позволяет использовать продукт, получать обновления, устанавливать решения из Маркетплейс, приоритетную техническую поддержку и т.д. (то о чем говорилось вначале). Срок действия Стандартной лицензии – один год. После этого необходимо продление.

2. Ограниченную – которая дает право использовать продукт без доступа к обновлениям и решениям из Маркетплейс. Владелец Ограниченной лицензии, если срок его Стандартной лицензии истек, получает техническую поддержку менее оперативно (срок ответа – до трех рабочих дней).

Ограниченная лицензия предоставляется не по письменному договору, а по EULA (лицензионное соглашение с конечным пользователем) и не учитывается в бухгалтерском учете. Ее назначение – подтверждение правомерности использования программного продукта клиентом по истечению годичного периода.

Срок действия Ограниченной лицензии совпадает со сроком исключительных прав на программный продукт (по статье 1281 ГК РФ).
Как осуществляется поставка? Получу ли я коробку/диск?
Все продукты «1С-Битрикс» поставляются в электронном виде по электронной почте. После подтверждения факта оплаты на e-mail, указанный при оформлении заказа, будет отправлено письмо с лицензионным ключом, инструкцией по его активации и получению дистрибутива, или купоном и инструкцией по активации купона.

Поставка программных продуктов “1С-Битрикс” на физических носителях (коробки/диски) не осуществляется.

esia-oauth2

Модуль для доступа к ЕСИА REST сервису (https://esia.gosuslugi.ru)

Основан на коде esia-connector https://github.com/eigenmethod/esia-connector, лицензия: https://github.com/eigenmethod/esia-connector/blob/master/LICENSE.txt

Позволяет:

  • Сформировать ссылку для перехода на сайт ЕСИА с целью авторизации
  • Завершает процедуру авторизации обменивая временный код на access token
  • Опционально может производить JWT (JSON Web Token) валидацию ответа ЕСИА (при наличии публичного ключа ЕСИА)
  • Для формирования открепленной подписи запросов, в качестве бэкенда может использоваться
    модуль M2Crypto или openssl через системный вызов (указывается в настройках)
  • Выполнять информационные запросы к ЕСИА REST сервису для получения сведений о персоне:
    • Основаная информация
    • Адреса
    • Контактная информация
    • Документы
    • Дети
    • Транспортные средства

Установка:

pip install --upgrade git+https://github.com/sokolovs/esia-oauth2.git
pip install -r https://raw.githubusercontent.com/sokolovs/esia-oauth2/master/requirements.txt

Предварительные условия

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

openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -sha1 -keyout my_private.key -out my_public_cert.crt

Полученный в результате файл my_public_cert.crt должен быть привязан к информационной системе вашей организации
на сайте Госуслуг, а также направлен вместе с заявкой на доступ к ЕСИА
(подробнее см. документы http://minsvyaz.ru/ru/documents/?words=ЕСИА).

Внимание! С 01 апреля 2020 прекращается поддержка использования самоподписных сертификатов. Необходимо
получить ключ ГОСТ 2012 в одном из сертификационных центров и использовать алгоритм подписи ГОСТ Р 34.10-2012.
Для этого необходимо установить на сервере КриптоПРО CSP, установить контейнер с закрытым ключем, а так же
привязать сертификат связанный с закрытым ключем к своей информационной системе.

Для валидации ответов от ЕСИА потребуется публичный ключ, который можно запросить в технической поддержке ЕСИА,
уже после регистрации информационной системы и получения доступа к тестовой среде ЕСИА. Валидация опциональна.

Пример использования в Django

Создайте конфигурационный файл esia.ini следующего содержания:

[esia]
### Внимание! Все пути указываются относительно данного файла.
# Базовый адрес сервиса ЕСИА, в данном случае указана тестовая среда
SERVICE_URL: https://esia-portal1.test.gosuslugi.ru

# Идентификатор информационной системы, указывается в заявке на подключение
CLIENT_ID: MYIS01

# Публичный ключ/сертфикат (необязателен, используется только для m2crypto или openssl)
CERT_FILE: keys/my_public_cert.crt

# Приватный ключ (необязателен, используется только для m2crypto или openssl)
PRIV_KEY_FILE: keys/my_private.key

# Публичный ключ сервиса ЕСИА, для валидации ответов (необязателен)
JWT_CHECK_KEY: keys/esia_test_pub.key

# Адрес страницы, на которую будет перенаправлен браузер после авторизации в ЕСИА
REDIRECT_URI: http://127.0.0.1:8000/esia/callback/

# Адрес страницы, на которую необходимо перенаправить браузер после логаута в ЕСИА (опционально)
LOGOUT_REDIRECT_URI: http://127.0.0.1:8000

# Список scope через пробел. Указывается в заявке, openid при авторизации обязателен
SCOPE: openid http://esia.gosuslugi.ru/usr_inf

# Используемый крипто бэкенд: m2crypto, openssl (системный вызов)
# или csp (системный вызов утилиты cryptcp из состава КриптоПРО CSP)
CRYPTO_BACKEND: m2crypto

# SHA1 отпечаток сертификата связанного с закрытым ключем, смотреть по выводу certmgr --list
# (необязателен, используется только для csp)
CSP_CERT_THUMBPRINT: 5c84a6a58bbeb6578ff7d26f4ea65b6de5f9f5b8

# Пароль (пин-код) контейнера с закрктым ключем
# (необязателен, используется только для csp)
CSP_CONTAINER_PWD: 12345678

В свой urls.py добавьте:

(, ., ),
(, ., ),

В свой views.py добавьте:

 
 .  , 
 ...  
 .  , 

  ()

 ():
      ()
      .()
     ()

 ():
      {}
      ()
    []  .()
     (, )

 ():
      ()
     ..():
          {
            : .[],
            : .[],
        }
    :
          []
          .[]
          .[]
          .(, )
        # Для отключения JWT валидации ответов ЕСИА, можно так:
        # esia_client = esia_auth.complete_authorization(code, state, validate_token=False)

        # Запрос информации о персоне
          .()
          .()
          .()
          .()
          .()
          .()

        .()
        .()
        .()
        .()
        .()
        .()

    # Просто выводим информацию. Здесь далее должна идти внутренняя логика авторизации
    # вашей информационной системы.
     (.(, ., , ),
        )

Переделанная реализация интеграции с ЕСИА,
оргинальный вариант – https://github.com/eigenmethod/esia-connector

  1. переделал в процедурный стиль
  2. добавил поддержку шифрования по госту
  3. сделал отдельным сервисом в докере
  4. проапдейтил для текущей версии

как использовать (в основном все описано в регламенте, но писалось явно не для людей, потому приведу краткую версию, плюс
выстраданная выжимка из форумов и стаковерфлоу)

  1. нужно зарегистрировать свою информационную систему на госуслугах
  2. с апреля 2012 есиа перестал поддерживать шифрование по RSA, перешли на российский гост 2012, поэтому в отличие от
    оригинального проекта с самоподписанными RSA сертификатами протестировать работу не получится(хотя возможно на тестовом контуре и не
    отключали), в любом случае для самого ЕСИА нужно будет получить квалифицированную электронную цифровую подпись
    в аккредитованном центре, важно им сказать что подпись нужна для ЕСИА, она должна быть экспортируемой(должны выставить
    специальный флаг), плюс крайне желательно чтобы она сразу была в формате pem или человеческом pfx, но я таких не нашел.
    если выдадут стандартную крипто про на флешке (папочка с файлами primary.key, primary2.key, mask.key, mask2.key
    итд итп) – то потребуются дополнительные усилия чтобы выковырнуть оттуда приватный ключ. ну и напоминаю что хранение
    приватного ключа на сервере повышает шансы что его сопрут, поэтому не стоит эту эцп использовать для чегото важного,
    если у вас уже была эцп для налоговой или других дел, то лучше получить новую.
  3. нужно из эцп получить публичный и приватный ключи для того чтобы подложить их на сервер. сначала нужно установить
    эцп в систему с флешки, далее публичный ключ экспортируется обычным(даже триальным) клиентом крипто про, а вот с
    приватным придется повозиться, так как он экспортируется тем же клиентом но в нестандартном pfx формате. в интернете можно
    найти несколько способов(на хабре, на форуме крипто про, на форуме наг.ру) как преобразовать контейнер крипто про в
    нужный формат, или вытащить ключ из крипто про формата, но они все разной степени хакернутости, нормальным людям проще
    всего будет использовать утилиту для бэкапа приватных ключей криптопро P12fromGOST от Лисси (платная, но раньше они ее
    выкладывали бесплатно, можно найти ту версию). она экспортирует файлы в стандартный pfx файл. из пфх файла уже можно
    получить стандартный .pem файл стандартными командами для опенссл

openssl pkcs12 -in backup_keys.pfx -out backup_keys.pem -engine gost -nodes -clcerts (вроде бы она, проверять не буду, извините)

да, вам потребуется установленный openssl с поддержкой госта 2012, что может быть проблемой, так как в последних версиях(1.1.1) ее выпилили,
нужно брать версии 1.0.1(вроде бы), отдельно ставить гост энжин, который не со всеми версиями опенссл нормально работает, но как
вариант можно использовать докер образ уже собранный с рабочими версиями опенссл и гост энжин.
так же на стаковерфло был совет из пем файла удалить все лишние блоки (кроме блоков самих сертификатов
—-BEGIN —-сертификат —END—-, и поменять их местами – чтобы приватный ключ в пем файле шел первым, я на всякий
случай сделал, но может и так сработало бы)
так же в пем файле приватный ключ может быть зашифрован для большей защиты, я расшифровал. если хотите использовать в
зашифрованном виде то нужно будет еще впихнуть распаковку ключа по паролю

  1. подложить ключи(у меня единым файлом в .pem, но можно и отдельными) в папочку серт, туда же закинуть публичные ключи
    от теста и прода есиа (скачиваются с офсайта, ссылка есть в документации, единым файлом esia.zip)

  2. написать заявку на подключение вашей системы к ЕСИА, там нужно указать урл по которому будет доступна ваша система
    (чтобы есиа знала что на этот урл можно редиректирить пользователей), ее мнемоника (нужно придумать самому по правилам для
    смэва – по ней есиа будет искать сертификаты для проверки подписи вашей системы и прав доступа), приложить открытый ключ
    (сер файл в формате дер, если вы понимаете о чем я:), пем файл прикладывать не стоит так как там указан и приватный ключ

  • так же публичный ключ можно будет прикрепить самостоятельно и на проде, и на тесте(отдельно), найдя свою систему по мнемонике ),
    плюс указать список запросов к которым пользователь должен дать вам доступ (например fullname snils итд итп). после рассмотрения
    и утверждения заявки можно пробовать подключение к тестовому контуру есиа, потом для прода нужно будет просто поменять урл
    подключения.
  1. запустить фласк сервер отдельно или как сервис в докере

бонус, как оно работает

  1. вы на своем сайте должны сформировать специальный урл, и прикрутить его к кнопке войти через есиа
    в нем зашито (и подписано вашим приватным ключом) кто вы такие, чего вы хотите, и куда потом нужно юзера послать после логина в есиа.
  2. юзер кликает на кнопку, его перекидывает на сайт есиа, там он логинится, соглашается предоставить доступ к запрошенной
    вашей системой информации, после чего его браузер редиректит на ранее переданный редирект урл (который должен совпадать с
    зашитым урлом в настройках вашей системы в есиа, для тестового контура можно использовать локалхост). если логин прошел успешно,
    то есиа в параметрах к редирект урлу передает на ваш сайт специальный код, или сообщение об ошибке.
  3. после редиректа вы получаете на своем сервере на этом урле этот код, и используете его в новом запросе к есиа, уже от
    своей системы, для получения специальных аксесс и рефреш джвт токенов.
  4. аксесс токен уже можно использовать в конкретных запросах на получение параметров пользователя из есиа – имя, адрес,
    телефон итд итп

логи тестового контура есиа можно посмотреть по спец урлу, но желательно делать это в нерабочие часы, в рабочие все висит

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

  1. как стендэлон фласк сервер из своей системы – переименуйте файл .энв.экзампл в .энв, измените там необходимые параметры
    и далее просто python3 server.py из корня
  2. в докер контейнере – сначала соберите его командой
    docker build -t esia_conn . (<-точка в конце нужна, собирать и запускать все из корневой папки проекта)
    далее переименуйте докер-композ.ямл.экзампл в докер-композ.ямл измените в нем энв параметры и далее
    docker-compose up,
    или через докер ран
    docker run -p 5000:5000 esia_conn (+ нужно передавать энв переменные или использовать из энв файла)

Привет, Хабр! В одном из постов блога мой коллега Иван писал о нашем блокчейн-сервисе для онлайн-голосований WE.Vote. Он подробно разобрал, как работает WE.Vote с точки зрения технологий. Но чтобы сервисы удаленного голосования можно было использовать для принятия официальных решений юрлиц, не хватает еще одного важного компонента — достоверной верификации участников. В России для этого можно провести интеграцию с ЕСИА (Единой Системой Идентификации и Аутентификации) — проще говоря, с Госуслугами. Интеграция эта заметно отличается от интеграции с другими OAuth2-сервисами, как, например, Google или VK. В этом посте мы постараемся помочь тем, кто захочет интегрировать ЕСИА в свой сервис через стек, подобный нашему, а также дадим несколько полезных ссылок по ЕСИА в принципе.

Esia-gosuslugi

Зачем нам ЕСИА?

Согласно Федеральному закону № 225-ФЗ от 28.06.2021 «О внесении изменений в часть первую Гражданского кодекса Российской Федерации», многие организаций в РФ получили право проводить официальные собрания и голосования по корпоративным вопросам дистанционно.

Ранее решения с юридической силой требовали очных собраний или голосований по почте. Голосования по почте не отличаются надежностью, а собрать много руководителей со всей России в одном месте — это кошмар с точки зрения затрат.

Чтобы проводить мероприятия принятия решения дистанционно в соответствии с новым федеральным законом, необходимо предоставить возможность достоверного установления личности участников. В России это возможно через проверку доступа к верифицированному аккаунту на Госуслугах.

Стек и схема интеграции

Для интеграции мы используем:

  • Typescript, ReactJS, NestJS

  • КриптоПро CSP 4

Схема интеграции
Схема интеграции

Формирование подписи

Прежде чем разбирать все по порядку, кое о чем стоит подумать заранее. В отличие от других интеграций, запросы к ЕСИА должны сопровождаться подписью ГОСТ Р 34.10/11-2012, а не просто API key. Создать такую подпись можно с помощью утилиты КриптоПро CSP. Для нас основная задача здесь — правильно обернуть эту утилиту в Docker, чтобы с ней можно было работать как с отдельным сервисом в рамках нашей инфраструктуры. Получившийся сервис мы выложили в открытый доступ на гитхабе. Инструкция по запуску есть в README.md.

В процесс сборки Docker образа сервиса с утилитой КриптоПро мы встроили:

  • Установку утилиты КриптоПро СSP 4 из .deb пакета

  • Установку лицензии КриптоПро

  • Загрузку корневого сертификата тестовой или основной среды ЕСИА

  • Загрузку пользовательского сертификата с PIN кодом

  • REST-сервер с методом, позволяющим создавать подписи

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

private async signParams(params: Record<string, string>) {
 const time = moment().format('YYYY.MM.DD HH:mm:ss ZZ')
 const state = uuid()
 const clientId = this.clientId
 const scope = this.scope

 const { data: { result: clientSecret } } = await axios.post<{ result: string }>(
   `${this.cryptoProServiceAddress}/cryptopro/sign`,
   { text: [scope, time, clientId, state].join('') },
 )

 return {
   ...params,
   timestamp: time,
   client_id: clientId,
   scope,
   state,
   client_secret: clientSecret.replace(/\n/g, ''),
 }
}

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

Создание ссылки для редиректа на страницу ЕСИА

Все начинается с того, что пользователь решает пройти авторизацию через ЕСИА. Создаем на бэкенде ссылку для перехода с использованием нашего инструмента формирования подписей.

async getAuthLink(redirectLink: string) {
 const params = await this.signParams({
   redirect_uri: redirectLink,
   response_type: 'code',
   access_type: 'offline',
 })
 const authQuery = new URLSearchParams(params)
 const authURL = `${this.esiaHost}/aas/oauth2/ac`
 return `${authURL}?${authQuery}`
}

В redirectLink необходимо указать адрес страницы, на которую ЕСИА перенаправит пользователя после успешной аутентификации. Созданную ссылку возвращаем на фронтенд и перенаправляем на нее пользователя.

Получение авторизационного токена ЕСИА

Запрос токена идентификации

После успешной аутентификации на странице ЕСИА пользователь возвращается на фронтенд приложения по указанному нами адресу. ЕСИА передаёт авторизационный токен в виде get-параметра code. Этот токен необходимо передать на бэкенд и запросить с его помощью идентификационный токен пользователя.

async getTokens(code: string) {
 try {
   const params = await this.signParams({
     grant_type: 'authorization_code',
     token_type: 'Bearer',
     redirect_uri: 'no',
     code,
   })
   const authURL = `${this.host}/aas/oauth2/te`
   const authQuery = new URLSearchParams(params)
   const { data: tokens } = await axios.post(`${authURL}?${authQuery}`)
   return {
     idToken: tokens.id_token,
     accessToken: tokens.access_token,
     refreshToken: tokens.refresh_token,
   }
 } catch (e) {
   const status = e.response ? e.response.status : 500
   const message = e.response ? e.response.data.error_description : e.message
   throw new HttpException('Failed to get auth tokens: ' + message, status)
 }
}

Получение данных о пользователе

Идентификационный токен пользователя необходимо проверить с помощью публичного RSA ключа от ЕСИА и получить из него id пользователя. С помощью этого id и accessToken, который мы получили в предыдущем шаге, мы уже наконец можем запросить персональные данные пользователя.

getUserIdFromToken(idToken: string) {
 const decodedIdToken = verify(idToken, this.esiaPublicKey, {
   algorithms: ['RS256'],
   audience: 'WE_VOTE',
 }) as EsiaParsedToken
 return decodedIdToken['urn:esia:sbj']['urn:esia:sbj:oid']
}

async getUserInfo(tokens: EsiaTokens) {

 const { idToken, accessToken } = tokens
 const oId = this.getUserIdFromToken(idToken)

 const [{ data: mainInfo }, { data: contactsInfo }] = await Promise.all([
   axios.get(`${this.esiaHost}/rs/prns/${oId}`, {
     headers: {
       Authorization: `Bearer ${accessToken}`,
     },
   }),
   axios.get(`${this.esiaHost}/rs/prns/${oId}/ctts?embed=(elements)`, {
     headers: {
       Authorization: `Bearer ${accessToken}`,
     },
   }),
 ])

 const email = contactsInfo.elements.find(({ type }: { type: string }) => type === 'EML')

 return {
   id: oId,
   firstName: mainInfo.firstName,
   lastName: mainInfo.lastName,
   surName: mainInfo.middleName,
   trusted: mainInfo.trusted,
   email: email ? {
     value: email.value.toLowerCase(),
     verified: email.vrfStu === 'VERIFIED',
   } : null,
 }
}

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

Полный код интеграционного модуля на бэкенде
import { HttpException } from '@nestjs/common'
import * as moment from 'moment'
import { v4 as uuid } from 'uuid'
import { URLSearchParams } from 'url'
import axios from 'axios'
import { verify } from 'jsonwebtoken'

type EsiaTokens = {
 idToken: string,
 accessToken: string,
}

type EsiaParsedToken = {
 'urn:esia:sbj': {
   'urn:esia:sbj:oid': string,
 },
}

export class EsiaApiService {
 private readonly clientId = 'WE_VOTE'
 private readonly scope = ['openid', 'email', 'fullname'].join(' ')

 constructor(
   private readonly esiaHost: string, // 'https://esia-portal1.test.gosuslugi.ru' или 'https://esia.gosuslugi.ru'
   private readonly esiaPublicKey: string, // можно взять из http://esia.gosuslugi.ru/public/esia.zip
   private readonly cryptoProServiceAddress: string, // адрес сервиса по созданию подписей e.g 'http://127.0.0.1:3037'
 ) {
 }

 async getAuthLink(redirectLink: string) {
   const params = await this.signParams({
     redirect_uri: redirectLink,
     response_type: 'code',
     access_type: 'offline',
   })
   const authQuery = new URLSearchParams(params)
   const authURL = `${this.esiaHost}/aas/oauth2/ac`
   return `${authURL}?${authQuery}`
 }

 private async signParams(params: Record<string, string>) {
   const time = moment().format('YYYY.MM.DD HH:mm:ss ZZ')
   const state = uuid()
   const clientId = this.clientId
   const scope = this.scope

   const { data: { result: clientSecret } } = await axios.post<{ result: string }>(
     `${this.cryptoProServiceAddress}/cryptopro/sign`,
     { text: [scope, time, clientId, state].join('') },
   )

   return {
     ...params,
     timestamp: time,
     client_id: clientId,
     scope,
     state,
     client_secret: clientSecret.replace(/\n/g, ''),
   }
 }

 async getTokens(code: string) {
   try {
     const params = await this.signParams({
       grant_type: 'authorization_code',
       token_type: 'Bearer',
       redirect_uri: 'no',
       code,
     })
     const authURL = `${this.esiaHost}/aas/oauth2/te`
     const authQuery = new URLSearchParams(params)
     const { data: tokens } = await axios.post(`${authURL}?${authQuery}`)
     return {
       idToken: tokens.id_token,
       accessToken: tokens.access_token,
       refreshToken: tokens.refresh_token,
     }
   } catch (e) {
     const status = e.response ? e.response.status : 500
     const message = e.response ? e.response.data.error_description : e.message
     throw new HttpException('Failed to get auth tokens: ' + message, status)
   }
 }

 getUserIdFromToken(idToken: string) {
   const decodedIdToken = verify(idToken, this.esiaPublicKey, {
     algorithms: ['RS256'],
     audience: this.clientId,
   }) as EsiaParsedToken
   return decodedIdToken['urn:esia:sbj']['urn:esia:sbj:oid']
 }

 async getUserInfo(tokens: EsiaTokens) {

   const { idToken, accessToken } = tokens
   const oId = this.getUserIdFromToken(idToken)

   const [{ data: mainInfo }, { data: contactsInfo }] = await Promise.all([
     axios.get(`${this.esiaHost}/rs/prns/${oId}`, {
       headers: {
         Authorization: `Bearer ${accessToken}`,
       },
     }),
     axios.get(`${this.esiaHost}/rs/prns/${oId}/ctts?embed=(elements)`, {
       headers: {
         Authorization: `Bearer ${accessToken}`,
       },
     }),
   ])

   const email = contactsInfo.elements.find(({ type }: { type: string }) => type === 'EML')

   return {
     id: oId,
     firstName: mainInfo.firstName,
     lastName: mainInfo.lastName,
     surName: mainInfo.middleName,
     trusted: mainInfo.trusted,
     email: email ? {
       value: email.value.toLowerCase(),
       verified: email.vrfStu === 'VERIFIED',
     } : null,
   }
 }

}

Надеюсь, статья оказалась для вас полезной. Желаю, чтобы у вас все получилось без особых проблем! 

Полезные материалы по теме

Читайте также:  Для граждан Российской Федерации новые пособия начнут выдавать с 1 января 2016 года
Оцените статью