What's the best practice for redirecting the user, using Devise, back to the page she is currently on after she logs out?
The devise docs say to override the following (in your application controller):
def after_sign_out_path_for(resource_or_scope)
# logic here
end
Which is easy enough. However, I'm setting the previous page to be a session variable, like this:
session[:return_to] = request.fullpath
The problem is that when you sign out, the session is destroyed, and the top method occurs AFTER the session is destroyed, meaning you no longer have access to it. I'm thinking of putting it in a class variable or something similar, but wanted to see what SO thought.
If you are always using the page where the logout link was clicked you could use the referrer on the request.
def after_sign_out_path_for(resource_or_scope)
request.referrer
end
if you want to redirect user to sign in page after sign out write the below function in you application controller
def after_sign_out_path_for(resource_or_scope)
new_user_session_path
end
Related
I've found a seemingly solution to my problem but I keep on getting an internal server error.
def after_sign_in_path_for(resource)
current_user_path
end
I currently have a user model and an admin model and I want both to go to the same web page. Is what the method after_sign_in_path_for takes in as a parameter supposed to be the model I want to use? I'm not sure what the (resource) is in this context...
I think def after_sign_in_path_for(resource) is already correct, the only problem is current_user_path, you can use as follow
def after_sign_in_path_for(resource)
user_path(current_user)
end
If I access http://example.com, I am first taken to the login page and after successful login, to the home page.
If I access http://example.com/myusers, after successful login, I want to be redirected to the current page and not the home page.
After reading a few online posts, I understood that in my application_controller.rb I can manipulate the after_sign_in_path_for method. I tested this by adding a specific url to this method and I always get redirected to that url after a successful login.
def after_sign_in_path_for(resource)
"http://example.com/users"
end
How can I make this method capture the URL that the user requested before signing in and redirect the user accordingly?
Devise comes with something like this out-of-the-box. As part of the failure scenario it stores the last request. This "How-to" should help you with the solution. Note that you need to call this method in your before_filter of the controller(s):
before_filter: authenticate_user!
https://github.com/plataformatec/devise/wiki/How-To:-Redirect-back-to-current-page-after-sign-in,-sign-out,-sign-up,-update#a-simpler-solution
You can store the requested URL in a session variable.
session[:return_to] = request.original_url
You can set the session variable inside of an before_action :authorize method in your application controller, this may make sense somewhere else depending on your authorization strategy.
def authorize
if current_user_authorized?
# Authorized...
else
# Record the requested page URL and redirect to the login page.
session[:return_to] = request.original_url
redirect_to login_url, error: "Not authorized."
end
end
To use it you can write:
def after_sign_in_path_for(resource)
session[:return_to] || root_url
end
I have used this how-to to redirect back to current page after sign in, sign out using Devise.
It is almost always working but one case is not.
I also have redirected to login page after logout. Without this redirection everything is working.
The case that is not working is: when I logout and login again. In the login page I print session[:previous url] and it is empty and after login, it redirects to the root path·
This behavior seems pretty strange to me... Any ideas?
UPDATE
This is the redirection that I mentioned. This way, session[:previous url] is empty in the login page
def after_sign_out_path_for(resource)
login_path
end
This is how it is working without the redirection. This way, session[:previous url] is working properly
def after_sign_out_path_for(resource)
session[:previous_url] || root_path
end
You need to override the Devise's method after_sign_out_path_for to achieve this. In your application controller add this method
def after_sign_out_path_for(resource_or_scope)
request.referrer
end
I know it's a very old question but many people (including me) still have this problem.
Devise resets the session during logout so as RSB wrote, you need to use request.referrer to redirect user back to where they came from.
In your specific case you may want to change the method to following
def after_sign_out_path_for(resource_or_scope)
session[:previous_url] = request.referrer
redirect_to login_path
end
However expecting the app to remember where user was when they log out and log back in is... quite exotic.
I'm trying to figure out how to get the user to be returned back to the original page after they sign up or sign in to the site through Devise.
For instance: User is viewing Listing A. User clicks "Sign Up", signs up successfully (no confirmation). But instead of being redirected back to the root, they're returned back to Listing A.
I used to do this with my homegrown authentication by storing the original URL in the session, then on successful login, redirect to the stored URL, or continue onto the default page if it is null.
Can I do the same thing with Devise, or is there a preferred way of achieving the same thing?
THE ANSWER
After wracking my brain for hours, then posting a SO question, it hits me almost immediately after submitting the question. Here's how I did it:
In my application controller, I sniff to see if there is a return_to params in the URL. If there is, I set that in the session.
Then, I overwrite after_sign_in_path_for in the application controller to redirect to the stored session value or root_path.
Here's (the pertinent parts of) my application_controller.rb:
class ApplicationController < ActionController::Base
before_filter :check_for_manual_return
def check_for_manual_return
session[:return_to] = params[:return_to] if !params[:return_to].nil?
end
def after_sign_in_path_for(resource)
return session[:return_to] || root_path
end
end
So I want to send emails to users with some links which you can click on to do things, but if the user isn't already logged in, I'd like to be able to let the user log in and then redirect him back to what he was trying to get to.
I have these methods in application_controller.rb
This is called as a before_filter on the place the URL links to, catches that the user shouldn't be wherever he is trying to go and stores the intent
def user_in_beta
unless user_signed_in? && current_user.beta
if user_signed_in?
redirect_to :home_betawait
else
session[:original_uri] = request.request_uri
redirect_to new_user_session_path
end
end
end
And this should catch him after he signs in and put him back where he belongs.
def after_sign_in_path_for(resource_or_scope)
if current_user.beta
if session[:original_uri].nil?
:home_index
else
session[:original_uri]
end
else :home_betawait
end
end
However, it does not. Instead I get a very nasty "cannot redirect to nil!" If I read it into a local variable and store it, even more things break. I am very baffled, this has to be an extremely common thing to want to do.
I'd like to be able to let the user
log in and then redirect him back to
what he was trying to get to.
This behavior is already provided by Devise's authenticate_user! before_filter. Since your "devise" tag on this story and use of user_signed_in? suggest that you are already using Devise why reinvent your own solution?