Rails 4 - Devise,访客用户导致过滤器链停止 [英] Rails 4 - Devise, guest users causes filter chain halted

查看:101
本文介绍了Rails 4 - Devise,访客用户导致过滤器链停止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始使用Rails 4(4.2.3)应用程序,其中我使用 Devise 进行用户身份验证。我希望用户能够通过创建一个测试项目并以访客用户身份登录,然后再注册该应用。当用户注册(或)时,我想将测试项目分配给新的当前用户。



我已经从Platformatec了解本指南: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user



创建访客用户的工作原理,但是在注册或使用活动的访客用户会话时,我收到以下错误:

 过滤器链停止为:require_no_authentication呈现或重定向

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

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

如上所述,创建访客用户似乎工作正常。但这个逻辑永远不会发生:

 #应该删除来宾用户并清除会话。 
如果current_user
如果session [:guest_user_id]&& session [:guest_user_id]!= current_user.id
logging_in
guest_user(with_retry = false).try(:destroy)
会话[:guest_user_id] = nil
end
current_user

我很确定我的访客用户会话与我的新用户冲突,导致设计错误(由于访客用户永远不会在注册时被删除):

 过滤链停止为:require_no_authentication呈现或重定向

其余的访客用户逻辑看起来或多或少与此链接的指南完全相同: https://github.com/plataformatec/devise/wiki/How-To: - 创建-A-来宾用户。我还添加了认证段落/示例中的代码: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user#authentication-this-may-interfere -with-the-current_user-helper



任何关于我失踪的想法,以及如何获取我的 current_or_guest_user 在使用Devise时删除访客用户注册和签名?



更新



这是我的路线目前看起来如何:

  devise_for:users,controllers:{sessions:用户/会话,注册:用户/注册} 

root:to => 'public#index'

resources:apps

get'users / show',to:users#show
get'users',to:用户#index

post'guests / receive_guest',至:guest#receive_guest

更新2



本指南具有以下声明:


当(和)用户注册或登录时,我们删除访客用户
并清除会话变量。


它并没有说明如何和在哪里做。我猜想我必须再次呼叫 current_or_guest_user 。但我不知道自己不熟悉Devise的地方。



更新3



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


  1. 用户创建一个测试项目。

  2. 创建测试项目后,将创建一个访客用户和会话。访客用户应该在会话结束后被删除,或#3。

  3. 如果访客用户注册,他/她应该登录,测试项目应该被分配到新的真实用户。

  4. 访客用户应该被删除。


解决方案

感谢您的答案skahlert和SsouLlesS。跳过守门员策略确实帮助和定义回调似乎是一个干净的方法。除了我还有一些其他问题。



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

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

然后我做了skahlert建议,删除了 warden策略 / p>

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

 #POST / resource 
def create
#删除访客用户并重置会话
new_user_from_guest = guest_user
guest_user(with_retry = false).try(:destroy)
会话[:guest_user_id] = nil

build_resource(sign_up_params)

resource.save
产生资源如果block_given?
if resource.persisted?
如果resource.active_for_authentication?
set_flash_message:notice,:signed_up if is_flashing_format?
sign_up(resource_name,resource)

#将访客用户应用程序分配给新的当前用户。
new_user_from_guest.apps.each do | app |
app.user_id = current_user.id
app.save!
end
respond_with资源,位置:after_sign_up_path_for(资源)
else
set_flash_message:notice,:signed_up_but _#{resource.inactive_message}if is_flashing_format?
expire_data_after_sign_in!
respond_with资源,位置:after_inactive_sign_up_path_for(资源)
end
else
#重置测试用户如果注册失败,我还没有测试这部分。
guest_user
guest_user.apps<<< new_user_from_guest.apps
guest_user.save!

clean_up_passwords资源
set_minimum_password_length
respond_with资源
结束
结束

一切似乎都在工作。可以做一些重构,并可能尝试SsouLlesS在他的答案中建议的回调方法。


I have just started working on a Rails 4 (4.2.3) app where I use Devise for user authentication. I want users to be able to play around with the app before signing upp by creating a test project and be signed in as a guest user. When the user signs up (or in) I want to assign the test project to the new current user.

I have been following this guide from Platformatec: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user

Creating the guest user works, but when signing up or in with an active guest user session I get the following error:

Filter chain halted as :require_no_authentication rendered or redirected

If I clear my session it works. The method that manages my guest user looks like this:

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

As mentioned, creating guest users seems to work just fine. But this logic never happens:

# 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

I'm pretty sure that my guest user session is conflicting with my new user and causes this Devise error (since the guest user never gets deleted on sign up):

Filter chain halted as :require_no_authentication rendered or redirected

The rest of my guest user logic looks more or less exactly like this linked guide: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user. I also added the code from the Authentication paragraph / example: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user#authentication-this-may-interfere-with-the-current_user-helper.

Any ideas on what I'm missing, and how I can get my current_or_guest_user to delete the guest user on signup and signing when using Devise?

Update

This is how my routes look currently:

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"

Update 2

The guide have the following statement:

When (and if) the user registers or logs in, we delete the guest user and clear the session variable.

It doesn't explain much how and where to do it. I'm guessing I have to call current_or_guest_user somewhere again. But I'm not sure where since I'm not that familiar with Devise.

Update 3

To make it a bit more clear. This is the steps I want to achieve.

  1. User creates a test project.
  2. Upon creation of the test project a guest user and session gets created. The guest user should get deleted once the session ends or #3.
  3. If the guest user signs up, he /she should get logged in and the test project should get assigned to the new real user.
  4. The guest user should get deleted.

解决方案

Thanks for your answers skahlert and SsouLlesS. Skipping the warden strategy did help and defining callbacks seems like a clean approach. Beside that I had some other issues.

One was that my custom Devise controllers never got called. Created another question for that: Rails 4 - devise_for not using custom controllers. The solution was that I used the wrong url in my modal signup form. My form now looks like this:

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

Then I did as skahlert suggested and removed the warden strategy from my app.

Once my custom devise Users::RegistrationsController < Devise::RegistrationsController controller got called I decided to override the create action. It's not completely tested, but it looks like this:

# 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

Everything seems to work now. Could do some refactoring and possibly try the callback approach that SsouLlesS suggested in his answer.

这篇关于Rails 4 - Devise,访客用户导致过滤器链停止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆