Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Devise redirect back to the original location after sign in or sign up?

Here I'm using Devise Gem for authentication. If someone want to open page without login then it redirect to sign_in page and after signed in it back to the page which user try to open. I use Redirect loop with Devise after_sign_in_path_for link for my problem but it does not work for me.

 def after_sign_in_path_for(resource)
   params[:next] || super 
 end

It doesn't redirect back me to the page which I want to open. for example: If I want to open "127.0.0.1:3000/post/2/edit", it doest not back to this page after signed in.

like image 410
Rajeev Avatar asked Apr 11 '13 08:04

Rajeev


3 Answers

The best resource to seek is the official repo/wiki/issues, and then SO. The answer you found is out of date.

Here is the answer: https://github.com/plataformatec/devise/wiki/How-To:-Redirect-back-to-current-page-after-sign-in,-sign-out,-sign-up,-update

Just add the following in ApplicationController for versions devise > 3.2.1:

    # This example assumes that you have setup devise to authenticate a class named User.
class ApplicationController < ActionController::Base
  before_action :store_user_location!, if: :storable_location?
  # The callback which stores the current location must be added before you authenticate the user 
  # as `authenticate_user!` (or whatever your resource is) will halt the filter chain and redirect 
  # before the location can be stored.
  before_action :authenticate_user!

  private
    # Its important that the location is NOT stored if:
    # - The request method is not GET (non idempotent)
    # - The request is handled by a Devise controller such as Devise::SessionsController as that could cause an 
    #    infinite redirect loop.
    # - The request is an Ajax request as this can lead to very unexpected behaviour.
    def storable_location?
      request.get? && is_navigational_format? && !devise_controller? && !request.xhr? 
    end

    def store_user_location!
      # :user is the scope we are authenticating
      store_location_for(:user, request.fullpath)
    end
end

And then to redirect after signing in, you have to override this method:

def after_sign_in_path_for(resource_or_scope)
  stored_location_for(resource_or_scope) || super
end
like image 74
Billy Chan Avatar answered Oct 21 '22 12:10

Billy Chan


You don't need all this code. Devise (as the latest versions) already saves the location for you.

Just use this:

def after_sign_in_path_for(resource)
  request.env['omniauth.origin'] || stored_location_for(resource) || root_url
end

This will redirect user to the latest omniauth.source, or the stored_location and is last case, the root url.

I thought I was required to create that method, but Devise already does it.

Source: https://github.com/plataformatec/devise/wiki/How-To:-redirect-to-a-specific-page-on-successful-sign-in

like image 30
Tsuharesu Avatar answered Oct 21 '22 11:10

Tsuharesu


As of Devise 4, it worked seamlessly for me:

Devise automatically redirects on sign in and sign up as long as you store the location of the current page using devise's store_location_for(resource). To do this, edit your ApplicationController in app/controllers/application_controller.rb. Add:

# saves the location before loading each page so we can return to the
# right page. If we're on a devise page, we don't want to store that as the
# place to return to (for example, we don't want to return to the sign in page
# after signing in), which is what the :unless prevents
before_filter :store_current_location, :unless => :devise_controller?

private
  # override the devise helper to store the current location so we can
  # redirect to it after loggin in or out. This override makes signing in
  # and signing up work automatically.
  def store_current_location
    store_location_for(:user, request.url)
  end

Add the following to the ApplicationController to make sign out redirect:

private
  # override the devise method for where to go after signing out because theirs
  # always goes to the root path. Because devise uses a session variable and
  # the session is destroyed on log out, we need to use request.referrer
  # root_path is there as a backup
  def after_sign_out_path_for(resource)
    request.referrer || root_path
  end
like image 7
joshweir Avatar answered Oct 21 '22 11:10

joshweir