/esia-ruby

A Ruby interface and helpers to the ESIA

Primary LanguageRuby

!!! (Внимание) На данный момент в разработке. Если хочешь помочь с проектом, то велком

ЕСИА

Методы и классы для авторизации через ЕСИА и получения данных по API

TODO:

  1. Реализовать остальные методы API
  2. Улучшить интерфейсы ответов из ЕСИА (избавиться от сокращений по типу "sbj_id")
  3. Реализовать стратегию для omniauth
  4. Переписать расширение на GO с использованием последней версии gogost и без постоянного чтения из файла
  5. Написать тесты
  6. Подробно описать процесс получения и регистрации сертификата
  7. Написать инструмент для замены P12FromGostCSP - OpenSource и без Windows
  8. Добавить инструкцию по установке на сервер без доступа в интернет
  9. Добавить sig файлы (RBS)
  10. Добавить yard документацию кода
  11. Улучшить базовую документацию
  12. Провести нагрузочное тестирование
  13. Выложить на rubygems

Установка

  1. Добавляем в Gemfile: gem 'esia-ruby', github: 'iwdt/esia-ruby'

  2. Получаем сертификат и регистрируем его в ЕСИА

  3. Необходимо иметь флешку или КриптоПРО контейнер (набор файлов - header.key, masks.key, masks2.key, name.key, primary.key, primary2.key) и пароль

  4. Сконвертировать ЭЦП в PCKS#12

    • Скачиваем и устанавливаем КриптоПРО CSP (триальной версии достаточно)
    • Запускаем "Инструменты КриптоПРО"
    • Переходим во вкладку Контейнеры, он подгрузит контейнер "MySite.001" с флешки (у него будет уже нормальное имя), жмем Импортировать
    • Покупаем и устанавливаем P12FromGostCSP
    • Запускаем P12FromGostCSP, он подгрузит ключ из КриптоПРО. Жмем Экспортировать, выбираем папку
    • Мы получили файл в фомате pfx
  5. Сконвертировать сертификат и ключ в pem формат

    • Переходим в директорию с файлом p12.pfx
    • Формируем приватный ключ
      docker run --rm -v `pwd`:`pwd` -w `pwd` -it rnix/openssl-gost openssl pkcs12 -in p12.pfx -nocerts -out key.pem -nodes`
    • Формируем сертификат
      docker run –rm -v `pwd`:`pwd`-w `pwd` -it rnix/openssl-gost openssl pkcs12 -in p12.pfx -nokeys -out cert.pem
    • Сохраняем в удобное место файлы key.pem и cert.pem
  6. (Опционально) Проверем что все прошло успешно

    • Генерим публичный ключ

      docker run –rm -v `pwd`:`pwd` -w `pwd` rnix/openssl-gost openssl x509 -pubkey -noout -in cert.pem > pubkey.pem
    • Создаем сообщение

      echo "Some Data" > file.txt
    • Подписываем сообщение

      docker run --rm -v `pwd`:`pwd` -w `pwd` rnix/openssl-gost openssl dgst -md_gost12_256 -sign key.pem file.txt | base64 > signed.txt
    • Раскодируем из base64 в бинарный формат:

      base64 -D -in signed.txt > signed.bin
    • И проверяем подпись, сравнивая с исходным файлом и подписью:

      docker run --rm -v `pwd`:`pwd` -w `pwd` rnix/openssl-gost openssl dgst -md_gost12_256 -verify pubkey.pem -signature signed.bin file.txt

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

  1. Настройка:

    • Сертификат и приватный ключ в формате .pem кладем в удобное место
    • Глобальные настройки подключения к ЕСИА
    require 'esia-ruby'
    
    ESIA.configure do |config|
      config.certificate_path = Rails.root.join('config/credentials/cert.pem').to_s # Полный путь до сертификата
      config.private_key_path = Rails.root.join('config/credentials/key.pem').to_s # Полный путь до приватного ключа
      config.scope = "openid fullname contacts email mobile" # Список разрешений
      config.client_id = "CLIENT_ID" # Зарегестрированный в ЕСИА client id
      config.base_url = "https://esia-portal1.test.gosuslugi.ru" # Базовая ссылка на ЕСИА
    end
    • Создаем клиент для запросов:
    client = ESIA::Client.new
    • Получаем ссылку перехода пользователя для авторизации:
    uri = client.oauth2_uri(redirect_to: 'http://localhost:3000/auth/esia/callback')
    • После успешной авторизации, пользоваетеля переведет на ранее указанный redirect_to с переданными query string параметрами code и state. Нам необходимо code обменять на токен:
    code = params[:code]
    token = client.fetch_token code: code, redirect_to: 'http://localhost:3000/auth/esia/callback'
    • Получаем пользователя:
    user = client.fetch_user token: token
    • Получаем контакты:
    contacts = client.fetch_contacts token: token, params: { embed: '(elements)' }