OmniAuth Rails

OmniAuth - библиотека стандартизирующая аутентификацию через различных провайдеров  в веб-приложении. Библиотека создавалась чтобы быть мощной, гибкой и в тоже время "маленькой" насколько это возможно. Любой разработчик может создать стратегию для OmniAuth которая сможет аутентифицировать пользователей из разных несовместимых между собой систем (приложений). OmniAuth стратегии создаются для любых случаев от Facebook до LDAP.

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

Одна из стратегий называется Developer, она включена в OmniAuth и предоставляет полностью НЕбезопасный, полностью НЕпригодную  к использованию в production стратегию, которая запрашивает  у пользователя данные авторизации напрямую. Эту стратегию можно использовать как  заглушку при начале разработки и затем легко заменить/переключить на реальную стратегию.

Каждая стратегия OmiAuth это Rack Middleware. Это означает, что стратегии используются также как и любое другое middleware.

class MyApplication < Sinatra::Base
  use Rack::Session::Cookie
  use OmniAuth::Strategies::Developer
end

OmniAuth изначально создан для возможно аутентификации через разных провайдеров, то можно указать несколько разных провайдеров одновременно. Для это используется OmniAuth::Builder класс. Стоит отметить, что не никакой разницы между использованием каждой стратегии как  middleware или инициализации через OmniAuth::Builder  

# config/inizializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :developer unless Rails.env.production?
  provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']
end

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

Интеграция

Библиотека создана как "черный ящик", в который пересылаются данные пользователей приложения, которых нужно аутентифицировать и возвращаются обратно. OmniAuth специально не имеет ассоциации с моделью User и не делает предположений сколько методов аутентификации используется в приложении, а также что будет с данными пользователя послу аутентификации. Такой подход делает библиотеку невероятной гибкой. Для использования OmniAuth нужно перенаправить пользователя на /auth/:provider, где :provider это имя стратегии. Уже здесь OmniAuth позаботится о всех остальных шагах аутентификации для выбранной стратегии.

Пользователь аутентифицирован, что дальше? OmniAuth создает специальный хешб называемый Authentication Hash в Rack окружении запроса на `/auth/:provider/callback`. Этот хеш содержит информацию о пользователе, которую  OmniAuth смог получить из используемой стратегии. Необходимо создать конечную точку в приложении соответствующую URL обратного вызова стратегии и выполнить все необходимые шаги, соотвествующие требованиям приложения. Для примера, приложение Rails:

# routes.rb
get '/auth/:provider/callback', to: 'session#create'

и в SessionController

class SessionController < ApplicationController
  def create
    @user = User.find_or_create_from_auth_hash(auth_hash)
    self.current_user = @user
    redirect_to '/'
  end
                                               
  protected

  def auth_hash
    request.env['omniauth.auth']
  end
end

Ключ omniauth.auth в request.env содержит Authentication Hash с информацией о аутентифицированном пользователе включая уникальный идентификатор, стратегию используемую для аутентификации, персональные данные (имя, email и др. если доступно). Более подробное описание здесь.  

OmniAuth не выполняет никаких действий  кроме установки  переменных среды  в запросе обратного вызова. Реализовать логику процесса аутентификации в приложении потребуется самостоятельно.

Origin Param

Параметр origin url обычно используется для информирования о том, откуда пришел пользователь и куда, если вы решите его использовать, он захочет вернуться.

Три возможных варианта

По- умолчанию:

# /auth/twitter/?origin=[URL]
# No change
# If blank, `omniauth.origin` is set to HTTP_REFERER

Переименование параметра

# /auth/twitter/?return_to=[URL]
# If blank, `omniauth.origin` is set to HTTP_REFERER
provider :twitter, ENV['KEY'], ENV['SECRET'], origin_param: 'return_to'

Отключение параметра

# /auth/twitter
# Origin handled externally, if need be. `omniauth.origin` is not set
provider :twitter, ENV['KEY'], ENV['SECRET'], origin_param: false