设计,访客用户导致过滤器链停止

我刚刚开始研究Rails 4(4.2.3)应用程序,我使用Devise进行用户验证。 我希望用户能够在签署upp前通过创建测试项目来玩游戏,并以访客用户身份登录。 当用户注册(或在)时,我想将测试项目分配给新的当前用户。

我一直在关注Platformat的这个指南:https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user

创建访客用户可以工作,但在注册或处于活动访客用户会话时,出现以下错误:

Filter chain halted as :require_no_authentication rendered or redirected

如果我清除了会话,它就可以工作。 管理我的访客用户的方法如下所示:

def current_or_guest_user
  if current_user
    if session[:guest_user_id] && session[:guest_user_id] != current_user.id
      logging_in
      guest_user(with_retry = false).try(:destroy)
      session[:guest_user_id] = nil
    end
    current_user
  else
    guest_user
  end
end

如前所述,创建访客用户似乎工作得很好。 但是这个逻辑从未发生过:

# should delete the guest user and clear the session. 
if current_user
  if session[:guest_user_id] && session[:guest_user_id] != current_user.id
    logging_in
    guest_user(with_retry = false).try(:destroy)
    session[:guest_user_id] = nil
  end
  current_user

我非常肯定,我的访客用户会话与我的新用户冲突,并导致此Devise错误(因为来宾用户在注册时永远不会被删除):

Filter chain halted as :require_no_authentication rendered or redirected

我的访客用户逻辑的其余部分看起来或多或少完全像这个链接指南:https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user。 我还添加了验证段落/示例中的代码:https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user#authentication-this-may-interfere-with-the -current_user辅助。

关于我所缺少的任何想法,以及如何让我的current_or_guest_user在使用Devise时在注册和签名时删除访客用户?

更新

这是我的路线目前的样子:

devise_for :users, controllers: { sessions: "users/sessions", registrations:  "users/registrations" }

root :to => 'public#index'

resources :apps

get 'users/show', to: "users#show"
get 'users', to: "users#index"

post 'guests/receive_guest', to: "guests#receive_guest"

更新2

该指南具有以下声明:

当(如果)用户注册或登录时,我们删除来宾用户并清除会话变量。

它并没有解释如何以及在哪里做。 我猜我必须再次调用current_or_guest_user 。 但是我不确定在哪里,因为我不熟悉Devise。

更新3

为了更清楚一点。 这是我想要实现的步骤。

  • 用户创建一个测试项目。
  • 创建测试项目后,会创建一个访客用户和会话。 访客用户应该在会话结束或#3时被删除。
  • 如果访客用户注册,他/她应该登录并且测试项目应该被分配给新的真实用户。
  • 访客用户应该被删除。

  • 上面的答案缺乏解释, loggin_in方法没有被调用,因为你没有定义你的回调

    在您的ApplicationController中,您需要定义并设置回调,如下所示:

    define_callbacks :logging_in_user
    set_callback :logging_in_user, :before, :transfer_guest_user_actions_to_current_user
    
    def transfer_guest_user_actions_to_current_user
      # todo
    end
    

    你有没有尝试过使用设计客人的宝石? 它实现了开箱即用的功能,而不是从头开始......

    检查正在实现访客登录的示例控制器。 希望能帮助到你。


    我认为这个问题是由指南中引用的guest_user warden策略造成的。 由于Devise在登录前检查有效的监护会话,因此会显示重定向和Flash消息:

    if authenticated && resource = warden.user(resource_name)
      flash[:alert] = I18n.t("devise.failure.already_authenticated")
      redirect_to after_sign_in_path_for(resource)
    end
    

    所以如果你不严格需要认证! 方法来处理访客用户,您可以简单地停用该策略并且它应该可以工作。


    感谢您的回答skahlert和SsouLlesS。 跳过监狱战略确实有帮助,定义回调似乎是一种干净的方法。 除此之外,我还有其他一些问题。

    一个是我的自定义Devise控制器从未被调用过。 为此创建了另一个问题:Rails 4 - devise_for不使用自定义控制器。 解决方法是我在我的模式注册表单中使用了错误的网址。 我的表单现在看起来像这样:

    = form_for(resource, as: resource_name, url: user_registration_path do |f|
    

    然后我做了skahlert建议,并从我的应用程序中删除了监狱战略。

    一旦我的自定义设计Users::RegistrationsController < Devise::RegistrationsController控制器被调用,我决定覆盖创建操作。 它没有完全测试,但它看起来像这样:

    # POST /resource
    def create
      # Delete guest user and reset session. 
      new_user_from_guest = guest_user
      guest_user(with_retry = false).try(:destroy)
      session[:guest_user_id] = nil
    
      build_resource(sign_up_params)
    
      resource.save
      yield resource if block_given?
      if resource.persisted?
        if resource.active_for_authentication?
          set_flash_message :notice, :signed_up if is_flashing_format?
          sign_up(resource_name, resource)
    
          # Assign the guest users app to the new current user.
          new_user_from_guest.apps.each do |app|
            app.user_id = current_user.id
            app.save!
          end
          respond_with resource, location: after_sign_up_path_for(resource)
        else
          set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
          expire_data_after_sign_in!
          respond_with resource, location:  after_inactive_sign_up_path_for(resource)
        end
      else
        # Reset test user if signup fails, I have not tested this part yet. 
        guest_user
        guest_user.apps << new_user_from_guest.apps
        guest_user.save!
    
        clean_up_passwords resource
        set_minimum_password_length
        respond_with resource
      end
    end
    

    一切似乎现在工作。 可以做一些重构,并尝试使用SsouLlesS在回答中提出的回调方法。

    链接地址: http://www.djcxy.com/p/30497.html

    上一篇: Devise, guest users causes filter chain halted

    下一篇: Cannot execute Bash script from PHP