Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: Warden/Devise - How to capture the url before login/failed access

I am trying to figure out how to redirect a user to the page they logged in from (or failed to login) using Warden/Devise. I figure there is a session variable somewhere that is either available or could be made available.

E.g. Scenario 1: Non-authorized user goes to protected page X; Redirected to login page; User logs in; User redirected to protected page x

Scenario 2: Non-authorized user wants to take a protected action on page x; User clicks on login link; User logs in; User redirected to page x where the action is now available

Any pointers are appreciated.

Thanks!

like image 368
Alan McCann Avatar asked Aug 15 '10 20:08

Alan McCann


2 Answers

There is a devise helper method called after_sign_in_path_for(resource) (http://rdoc.info/github/plataformatec/devise/master/Devise/Controllers/Helpers) , and a session variable called session[:"user.return_to"] which stores the last url. The after_sign_in_path_for method needs to return a string, then devise automatically uses this path to redirect the user after login.

In my application controller I have put the following which redirects my users to the home page if the session variable is not set:

def after_sign_in_path_for(resource)
    (session[:"user.return_to"].nil?) ? "/" : session[:"user.return_to"].to_s
end
like image 58
jwebb Avatar answered Oct 08 '22 19:10

jwebb


If your using CanCan for authorization you can accomplish this be adding the following. If not, you should be able to adapt the concepts into your current authorization system.

app/controllers/application_controller.rb

  rescue_from CanCan::AccessDenied do |exception|
    flash[:error] = exception.message
    if user_signed_in?
      redirect_to root_url
    else
      # Adds the protected page to the login url but only if the user is not logged in
      redirect_to login_path(:next => request.path)
    end
  end

  def after_sign_in_path_for(resource_or_scope)
    # if a protected page found, then override the devise after login path
    params[:user]["next"] || super
  end

app/views/devise/sessions/new.html.erb

  <% if params[:next] %>
      <%= f.hidden_field :next, :value => params[:next] %>
  <% end %>

Instead of using session variables this solution uses params in the URL to keep track of the protected page.

like image 31
Austin Ginder Avatar answered Oct 08 '22 19:10

Austin Ginder