Skip to content

How To: redirect to a specific page on successful (oauth) #

Claas Z edited this page Mar 29, 2019 · 3 revisions

redirect back to current page after signin?

See How To: Redirect back to current page after #, sign out, #, update

redirect back to current page after oauth signin?

This is pretty straight forward, for an oauth #, 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 #. 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