【问题标题】:Integrating Wicked, Devise and Omniauth-Facebook集成 Wicked、Devise 和 Omniauth-Facebook
【发布时间】:2014-02-15 14:04:40
【问题描述】:

我正在使用我在这篇文章的标题中写的这三个 gem 开发一个应用程序。我使用可确认模块(?)设置了设计,因此当用户使用其电子邮件/密码创建帐户时,它会收到一封确认电子邮件。如果用户使用 facebook 注册(使用 omniauth-facebook gem),则设计会跳过确认步骤。

在user.rb中

    "Of course the :confirmable is active in the model"
    ...

    # Omniauth-facebook
    def self.find_for_facebook_oauth(auth)
      where(auth.slice(:provider, :uid)).first_or_create do |user|
        user.provider = auth.provider
        user.uid = auth.uid
        user.email = auth.info.email
        user.password = Devise.friendly_token[0,20]
        user.first_name = auth.info.first_name
        user.last_name = auth.info.last_name
        user.skip_confirmation!
        # user.image = auth.info.image # assuming the user model has an image
      end
    end

    ...

当我为巫师添加邪恶宝石时,事情就来了。我配置了路由文件

在 routes.rb 中

MyApp::Application.routes.draw do

  devise_for :users, :controllers => { :omniauth_callbacks =>  "users/omniauth_callbacks",
          :registrations => "registrations" }

  root 'home#index'

  # Registration wizard routes
  resources :after_register
end

我创建了一个registration_controller来覆盖设计注册方法

    class RegistrationsController < Devise::RegistrationsController

      def create
        super
      end

    protected

     def after_sign_in_path_for(resource)
       puts "<<<<<<<<<<<<<<<< SIGN IN"
       after_register_path(:import_contacts)
     end

     def after_sign_up_path_for(resource)
       puts "<<<<<<<<<<<<<<<< SIGN UP ACTIVE"
     after_register_path(:import_contacts)
   end

   def after_inactive_sign_up_path_for(resource)
    puts "<<<<<<<<<<<<<<<< SIGN IN INACTIVE"
    after_register_path(:import_contacts)
   end
 end

然后,我创建了一个新的控制器来处理带有 wicked 的向导的步骤。

   class AfterRegisterController < ApplicationController
     include Wicked::Wizard
     before_filter :authenticate_user!

     steps :import_contacts, :select_agents, :wish_form

     def show
       @user = current_user
       render_wizard
     end

     def update
       @user = current_user
       @user.attributes = params[:user]
       render_wizard @user
     end

   end

当我使用电子邮件/密码创建用户时,向导会出现并且一切正常,但是当我尝试使用 facebook 注册时,向导永远不会出现。

任何提示???

谢谢!!

【问题讨论】:

  • 你能告诉我你是如何使用 render_wizard 编写视图文件的

标签: ruby-on-rails ruby devise omniauth wicked-gem


【解决方案1】:

如果一切都以通常的方式配置(而且我所看到的看起来很标准),那么使用 Facebook 登录将根本不会通过 RegistrationsController。它将通过您尚未发布代码的OmniauthCallbacks 控制器进行。当他们通过 Facebook 登录时,这取决于您在那里做什么。我假设您有一个调用User.find_for_facebook_oauth(auth)facebook() 方法。那么您是否只是让他们登录而不是去RegistrationsController?如果是这样,那么RegistrationsController 将不会被触及,因此它被覆盖的after_sign_in_path_for 不会有任何效果。

如果您想让覆盖的after_sign_in_path_for 在整个应用程序中生效,您可以在ApplicationController 中定义它。如果你只希望它在你的OmniauthCallbacksController 中生效,你可以在那里定义它。无论哪种情况,他们每次使用 Facebook 登录时都会点击它(如果你把它放在 ApplicationController 中,每次有人使用任何方法登录时),所以你需要跟踪这个事实他们已经通过了向导,假设您想确保它仅在他们第一次登录时发生。如果您使用的是 devise :trackable 模块,也许检查 user.sign_in_count 是合适的,或者也许您有其他方法可以轻松检查他们是否已经通过向导。

评论问题更新:

您的第一个问题:“假设我将 after_sign_in_path_fot 放在 ApplicationController 中,我应该删除 RegistrationsController 中的 after_inactive_sign_up_path_for 方法,对吗?”这取决于你想要什么行为。在您的问题中使用RegistrationsController,它将在他们注册后并在他们确认电子邮件之前转到向导(因为在这种情况下将调用after_inactive_sign_up_path_for)。当他们确认并登录后,ApplicationController 中的after_sign_in_path_for 将再次将他们发送给向导。所以是的,如果您在登录后只需要向导,请从RegistrationsController 中删除非活动状态。那么RegistrationsController 中的after_sign_up_path_for(resource) 可能是不必要的,因为设计中的默认实现只调用after_sign_in_path_for(resource),您将在ApplicationController 中拥有它。无论如何,如果您总是需要确认,则不会调用 after_sign_up_path_for(),因为 RegistrationsController.create() 的默认实现中的逻辑 - 需要确认将导致 resource.active_for_authentication? 返回 false,从而导致调用 after_inactive_sign_up_path_for(resource)

对于您第二条评论中的问题,您说“如果我删除 ApplicationController 中的 after_sign_in_path_for” - 我假设您的意思是 RegistrationsController?如果这是正确的,那么是的,在 RegistrationsController 的覆盖版本中将不需要任何方法(如果这是您在问题中粘贴的整个控制器),因为您的 create() 只是调用 superafter_sign_in_path_for 将是在ApplicationController 中,您可能不想要上面讨论的任何after_(inactive)_sign_up_path_for 方法。所以是的,不需要你的RegistrationsController。您可以完全删除它并删除 routes.rb 中的 :registrations =&gt; "registrations" - 然后将再次使用 RegistrationsController 的设计实现。

然后你说“只是覆盖ApplicationController 中的RegistrationsController 的方法?”。您从RegistrationsController 中剩下的唯一方法是ApplicationController 中的after_sign_in_path_for(resource),所以我认为您的RegistrationsController 中不会有您需要在ApplicationController 中的任何其他方法。如果我错过了您的一项要求或做出了错误的假设,请告诉我。

【讨论】:

  • 感谢您的回答!是的,我发现 RegistrationsController 与 facebook 登录无关。我找到了一个解决方案,但它看起来比你的更脏(你的绝对更好)。我在用户模型中使用了一个新字段作为标志(它的作用与 sign_up_count 完全相同),然后在 OmniauthCallbacks 的 facebook 方法中调用@user.update_attribute(:flag, true)。假设我将 after_sign_in_path_fot 放在 ApplicationController 中,我应该删除 RegistrationsController 中的 after_inactive_sign_up_path_for 方法,对吗?谢谢!
  • 另一个问题。如果我删除 ApplicationController 中的 after_sign_in_path_for ,它里面就不会有任何方法。那么 routes.rb 中的 :registrations => "registrations" 会发生什么?我是否也必须删除它并仅覆盖 ApplicationController 中的 RegistrationsController 的方法?再次感谢!
  • 已编辑答案以包含您的问题的答案。抱歉现在有点长!
  • 哇!!多么好的和明确的答案,我的朋友!它真的帮助了我。谢谢!
猜你喜欢
  • 1970-01-01
  • 2014-05-30
  • 2013-08-02
  • 1970-01-01
  • 2016-02-26
  • 1970-01-01
  • 2015-11-26
  • 1970-01-01
  • 2014-09-17
相关资源
最近更新 更多