Rails 4 - development, guest users stop the filter chain

I just started working on a Rails 4 application (4.2.3), where I use Devise to authenticate users. I want users to be able to play with the application before signing upp by creating a test project and logging in as a guest user. When a user signs up (or logs in), I want to assign a test project to the new current user.

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

Creating a guest user works, but when I register or in an active guest user session, I get the following error:

 Filter chain halted as :require_no_authentication rendered or redirected 

If I clear the session, it will work. The method that controls my guest user is as follows:

 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 very well. 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 am sure that my guest session conflicts with my new user and causes this Devise error (since the guest user is never deleted during registration):

 Filter chain halted as :require_no_authentication rendered or redirected 

The rest of my guest logic looks something like this related guide: https://github.com/plataformatec/devise/wiki/How-To:-Create-a-guest-user . I also added the code from the paragraph / authentication 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 am missing, and how can I get my current_or_guest_user delete the guest user when registering and signing when using Devise?

Update

Here's what my routes currently look like:

 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 manual has the following statement:

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

This does not explain how and where to do it. I guess I should call current_or_guest_user again. But I'm not sure where, since I am not familiar with Devise.

Update 3

To make it more understandable. These are the steps that I want to achieve.

  • The user creates a test project.
  • After creating a test project, a guest user and session is created. Guest must be deleted after session or # 3.
  • If the guest user subscribes, he must log in, and the test project must be assigned to a new real user.
  • Guest must be deleted.
+7
authentication ruby ruby-on-rails ruby-on-rails-4 devise
source share
3 answers

Thanks for your answers skahlert and SsouLlesS. Skipping the oversight strategy helped, and defining callbacks seems clean. In addition, I had other problems.

One of them was that my Devise user controllers were never called. Created another question: Rails 4 - devise_for not using user controllers . The solution was that I used the wrong URL in my modal registration form. Now my form looks like this:

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

Then I did as Skolert suggested and removed the warden strategy from my application.

As soon as my custom development method Users::RegistrationsController < Devise::RegistrationsController received a call, I decided to override the create action. It is not fully 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 

Now everything works. Could do some refactoring and maybe try the callback approach proposed by SsouLlesS in his answer.

+1
source share

There is no explanation in the answer above, the loggin_in method loggin_in not called because you did not define your callback

In your ApplicationController, you need to define and then set the callback as follows:

 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 

Have you tried using the devise-guests gem? it implements this functionality out of the box, and does not do it from scratch ...

Check out this example that implements guest login. Hope this helps.

+1
source share

I think the problem is caused by the guest_user ranger strategy mentioned in the manual. Because Devise validates a valid Warden session before logging in, it causes a redirect and flash message:

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

So, if you do not need this authentication! A method for working with a guest user, you can simply disable this strategy, and it should work.

+1
source share

All Articles