在访问 Omniauth 路由之前验证设计用户
Posted
技术标签:
【中文标题】在访问 Omniauth 路由之前验证设计用户【英文标题】:Authenticate Devise User Before Accessing Omniauth Routes 【发布时间】:2015-01-16 01:24:47 【问题描述】:我正在开发一个应用程序,该应用程序将 devise 用于我的用户记录,将 omniauth 用于用户拥有的记录,而不是使用典型的 omniauth + devise 用于用户记录。我正在尝试将设计的用户身份验证添加到omniauth 路由/auth/:provider
,以便非注册访问者无法访问这些路由并触发特定提供商的身份验证过程。
我已经能够通过在我的 Sessions 控制器中使用 devise 的 authenticate_user!
辅助方法向回调添加身份验证,因此我至少阻止了未注册的访问者能够从omniauth 流创建记录,但是我想让设计的用户身份验证在omniauth流程的所有阶段都工作。
关于如何将 devise 的用户身份验证添加到初始omniauth 路由的任何想法,无论是使用类似于我当前解决方案的东西还是通过我的 routes.rb 文件使用 devise 的authenticate :user do
?
【问题讨论】:
【参考方案1】:在应用程序控制器中添加设计autheticate_user!
。
或者使用before filter
在omniauth认证方法之前调用它。
【讨论】:
这不起作用。将before_action :require_user
或 before_action :authenticate_user!
添加到应用程序控制器或 OmniauthCallbacksController 将只需要对 OmniAuth 回调进行身份验证,但在启动 OAuth 时不需要(OmniAuth 术语中的“请求阶段”)【参考方案2】:
这个解决方案对我有用。它本质上是创建一个新路由来检查用户当前是否已登录,然后将他们重定向到请求的提供者的授权路径。
routes.rb:
scope module: :authentication do
devise_scope :user do
# ...
get 'users/auth/:provider/setup', to: 'omniauth_callbacks#before_request_phase'
end
# ...
end
omniauth_callbacks_controller.rb:
def before_request_phase
authorize_path = send("user_#params[:provider]_omniauth_authorize_path".to_s)
if current_user.present?
redirect_to(authorize_path)
else
redirect_to login_path(return_to: authorize_path)
end
end
【讨论】:
【参考方案3】:任何有相同问题的人都可以在这里解决:
在 request_phase 中进行 Devise 身份验证。如果您正在使用策略 gem,例如,omniauth-facebook,您可以在初始化程序中修改该特定策略,例如,config/initializers/omniauth.rb
:
module FacebookExtension
include Devise::Controllers::Helpers
def request_phase
# it might be 'admin_user_signed_in?' depends on what your user model is
if user_signed_in?
super
else
# redirect to any path you think is suitable once devise authentication fail
redirect Rails.application.routes.url_helpers.new_admin_user_session_path
end
end
end
OmniAuth::Strategies::Facebook.prepend FacebookExtension
【讨论】:
【参考方案4】:我正在寻找一种解决方案,使我能够在提供者的基础上进行身份验证。以下示例适用于我。
config/initializers/omniauth.rb
内:
OmniAuth.config.before_request_phase = lambda do |env|
env['warden'].authenticate! if env['omniauth.strategy'].options.authenticate?
end
Rails.application.config.middleware.use OmniAuth::Builder do
provider :your_provider,
Rails.application.credentials.dig(:your_provider, :secret_id),
Rails.application.credentials.dig(:your_provider, :secret_key),
authenticate?: true
end
如果您想对所有提供者进行身份验证,只需删除策略上的 authenticate?
选项和 before_request_phase
调用中的检查即可。
【讨论】:
以上是关于在访问 Omniauth 路由之前验证设计用户的主要内容,如果未能解决你的问题,请参考以下文章
如何更新 twitter omniauth 访问令牌和访问令牌秘密