How To: redirect to a specific page on successful sign in

Anton Chumakov edited this page Sep 5, 2017 · 22 revisions

redirect back to current page after signin?

See How to: redirect to a specific page on successful sign in and sign out.

redirect back to current page after oauth signin?

This is pretty straight forward, for an oauth sign in, request.env['omniauth.origin'] is automatically set. You can also fall back to whatever you'd like:

class ApplicationController < ActionController::Base
  protected
    def after_sign_in_path_for(resource)
      request.env['omniauth.origin'] || stored_location_for(resource) || root_path
    end
end

Note this will only work if you are using devise to redirect a user after sign in. For example if you are using the sign_in_and_redirect helper:

sign_in_and_redirect @user

redirect back to current page without oauth signin?

class ApplicationController < ActionController::Base
  protect_from_forgery
        
  protected  
    def after_sign_in_path_for(resource)
      sign_in_url = new_user_session_url
      if request.referer == sign_in_url
        super
      else
        stored_location_for(resource) || request.referer || root_path
      end
    end
end

If you don't put stored_location_for before request.referer you'll get some weird behaviour and sometimes, you won't get to the stored location.

Add below snippet to new action of Devise::SessionsController if you want to customise redirect url

if params[:redirect_to].present?
  store_location_for(resource, params[:redirect_to])	
end

Or you can do this in a controller you inherit from Devise::SessionsController - first, in controllers/users/sessions_controller.rb:

module Users
  class SessionsController < Devise::SessionsController
   def new
     self.resource = resource_class.new(sign_in_params)
     store_location_for(resource, params[:redirect_to])
     super
   end
  end
end

In config/routes.rb, you would have also added:

devise_for :users, controllers: {sessions: 'users/sessions'}

Preventing redirect loops

Because the code for after_sign_in_path_for above only checks if request.referer == sign_in_url, these methods (which call after_sign_in_path_for) will also have to be overridden (else you will encounter redirect loops):

  • Devise::PasswordsController#after_resetting_password_path_for
  • Devise::RegistrationsController#after_sign_up_path_for
  • Devise::RegistrationsController#after_update_path_for

This can be done like so:

# routes.rb
devise_for :users, controllers: { registrations: 'users/registrations', passwords: 'users/passwords' }

# users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
  protected
    def after_sign_up_path_for(resource)
      signed_in_root_path(resource)
    end

    def after_update_path_for(resource)
      signed_in_root_path(resource)
    end
end

# users/passwords_controller.rb
class Users::PasswordsController < Devise::PasswordsController
  protected
    def after_resetting_password_path_for(resource)
      signed_in_root_path(resource)
    end
end
Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.