在访问 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_userbefore_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 访问令牌和访问令牌秘密

在 Vue 路由解析之前访问 Vuex

自动生成omniauth gem和路由

在 beforeEnter 路由中访问 VuexStore

Rails Devise Omniauth new_user_registration_url

路由错误未初始化常量用户