问题描述
我刚刚开始使用Rails 4(4.2.3)应用程序,其中我使用 Devise
进行用户身份验证。我希望用户能够通过创建一个测试项目并以访客用户身份登录,然后再注册该应用。当用户注册(或)时,我想将测试项目分配给新的当前用户。
我已经从Platformatec了解本指南:
创建访客用户的工作原理,但是在注册或使用活动的访客用户会话时,我收到以下错误:
过滤器链停止为: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呈现或重定向
其余的访客用户逻辑看起来或多或少与此链接的指南完全相同:。我还添加了认证段落/示例中的代码:。
任何关于我失踪的想法,以及如何获取我的 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
让它更清楚一点。这是我想要实现的步骤。
- 用户创建一个测试项目。
- 创建测试项目后,将创建一个访客用户和会话。访客用户应该在会话结束后被删除,或#3。
- 如果访客用户注册,他/她应该登录,测试项目应该被分配到新的真实用户。
- 访客用户应该被删除。
感谢您的答案skahlert和SsouLlesS。跳过守门员策略确实帮助和定义回调似乎是一个干净的方法。除了我还有一些其他问题。
一个是我的自定义Devise控制器从未被调用。创建了另一个问题: / 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:
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.
- User creates a test project.
- 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.
- If the guest user signs up, he /she should get logged in and the test project should get assigned to the new real user.
- 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,访客用户导致过滤器链停止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!