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