By default, Devise will redirect you to the root path after sign in. but sometimes we would like to redirect to the previous page where the anonymous user wanna access. This can be done by the following.
1. Create the app/helpers/sessions_helper.rb
module SessionsHelper def deny_access store_location redirect_to new_user_session_path end # add back anyone_signed_in? method after Oliver's comment @ 2011-03-12 def anyone_signed_in? !current_user.nil? end private def store_location session[:return_to] = request.fullpath end def clear_stored_location session[:return_to] = nil end end
2. Include the session helper and customize the Devise after_sign_in_path_for() in app/controllers/application_controller.rb
class ApplicationController < ActionController::Base protect_from_forgery include SessionsHelper # Customize the Devise after_sign_in_path_for() for redirecct to previous page after login def after_sign_in_path_for(resource_or_scope) case resource_or_scope when :user, User store_location = session[:return_to] clear_stored_location (store_location.nil?) ? "/" : store_location.to_s else super end end end
3. Request user to login in your controller
... def new if !anyone_signed_in? deny_access else @service = Service.new @title = "Create New Service" end end ...
Done =)
Reference:
- Rails Devise only redirects to a fixed path. Need to redirect back where the user came from when authentication was triggered.
- StackOverflow – Devise override redirect after form submit
- How To: Redirect to a specific page on successful sign in
Update @ 2011-09-23: If you are using omniauth, the following piece of code may help. Thanks for Allan. =D
def after_sign_in_path_for(resource_or_scope) if request.env['omniauth.origin'] request.env['omniauth.origin'] end end
This could be really useful if I can get it to work!
Where is the anyone_signed_in method defined?
LikeLike
Hi Oliver,
The anyone_signed_in? method is a helper method which is defined in a session helper and it is just simply
The current_user is provided by Devise. Replace the the anyone_signed_in? as follow should work.
hope this help =)
LikeLike
Why don’t you use user_signed_in? which is provided by Devise natively
LikeLike
I think it should be ok too. =P
LikeLike
After I posted, I tried using the current_user.nil and it worked that way for me! Thanks for the quick reply!
By the way, can I redirect to the create action? I want the user to enter details of the new record and when they click save, it asks them to login and then proceed to save the record.
Instead the code below redirects to the tenders index page. To get around it, I save the tender (using the session) in the deny_access method.
Can I redirect to the create (POST) action and still have access to the tender details that the user entered?
LikeLike
Hi Oliver,
I haven’t tried this before, but i think it should work.
probably you need to modify the after_sign_in_path_for(resource_or_scope) and put the tender save logic there instead of placing them in the create method.
Hope it works. =)
Kit
LikeLike
Thats what I did and it works perfect. Just hoping there might be a way of doing it without having to use a session variable!
LikeLike
then u have to store the form variables somewhere before the user login.
for example, you could add a column in the tenders table to store its status. then u can save the tender record even the user has not logged in yet. but in that record, just give it a “not complete” status. After the user has logged in, update the status to complete.
LikeLike
its really useful for me.. thanks ..
LikeLike
you are welcome =)
LikeLike
this is interesting…got this to work without sessions at all by using the request.referer
(request.referer.include? request.fullpath) ? redirect_url = current_user_path : redirect_url = request.referer
redirect_url
LikeLike
Thanks ben. but seems your code cannot be shown, could u posted again and wrapped the code with the following tag.
[sourcecode language=ruby]
Your code here…
[/sourcecode]
LikeLike
I believe Devise supports this inherently if you add
before_filter :authenticate_user_account!
to all your relevant controllers.
See the first answer here:
http://stackoverflow.com/questions/5359195/redirecting-after-a-login-to-the-original-task
LikeLike
O, thx for your information. i didn’t try that before. Need to find some time to update this post.
Thanks again =D
LikeLike
i believe this works if the user is forced to login, but if they click the login link without being forced into it, i am setting a session[:return_to] manually so that they are redirected to a certain page instead of the root url.
LikeLike
ic, thanks for clarifying that. =D
LikeLike
@danny , where are you setting this session[:return_to]? I have a similar issue and want to do the same.
LikeLike
@Igrabes, could u post more detail on your approach?
@danny, it would be great if you could help.
Thx =)
LikeLike
This was super helpful. I did the same thing as Oliver.
LikeLike
Glad to know that it could help. =)
LikeLike
This doesn’t seem to work if you want to send the user to users/password/new to reset their password. It always redirects them to “/”
LikeLike
Maybe you could try the comment made by magnemg
hope it could resolve the problem. =)
LikeLike
Thx, I done it
LikeLike
you are welcome. =D
LikeLike
We use Facebook JS to get the access code which then returns back to the omniauth_callback_controller.rb and signs the user in.
I found that the origin URL is saved in the request. Worked a treat for us.
in application_controller.rb
LikeLike
I have added this to the post. Thanks for the code. =D
LikeLike
after reading this entry, i write a page on devise wiki
https://github.com/plataformatec/devise/wiki/How-To:-Redirect-to-previous-page-on-successful-sign-in
LikeLike
Nice =D
LikeLike
hii
as per your instruction i do but i got message “The page isn’t redirecting properly”
what i do for fix this error.
LikeLike
I find a similar question on the google group.
Firefox has detected that the server is redirecting the request for this address in a way that will never complete.
* This problem can sometimes be caused by disabling or refusing to accept cookies.
Reference: Devise and i18n internationalization and Routes issue
Does it help?
LikeLike
this message shown in google chrome browser This webpage has a redirect loop
LikeLike
i guess there is a dead loop in the logic. Seems it keeps redirecting to itself so the loop never ends.
could u post your source code here?
LikeLike
LikeLike
LikeLike
new.html with in app/view/session
LikeLike
You will redirect the user to /login when deny_access. so is /login accessible for non-logged in user?
LikeLike
yes /login accessible for non- logged in user.
LikeLike
i use this filter before_filter :authorize ,:except=>[:create,:new]
method create and new used for login
LikeLike
after review of my code i found that i missplace this
can you help me.. what is the right place for this
with each and every secure function or any thing else
LikeLike
In the SessionController, replace the code as follow
And remove the anyone_signed_in? method as it is no longer used. Does it help?
LikeLike
thanks ..its work
but i m unable to redirect last page(secure page) from where user redirect to login page
LikeLike
So which page was shown after login? add some debug log in after_sign_in_path_for(resource_or_scope) and see if it was run. also check what is store in session[:return_to].
LikeLike
sorry, i think i m facing problem becuse i m useing restful_authentication…
if you have any idea for restful_authentication then let me inform
thanks a lot for your help
LikeLike
You are welcome. I didn’t help much at all. Wish you could solve the problem. =)
LikeLike
no problem
thanks once again for your continuous helpp
bye
LikeLike
This works like a charm.
I use devise 1.4 in one of my projects. Device actually stores the return path for us in session[resource_return_to], so in most cases, it would be session[:user_return_to]. This can save us a lot of custom code!
http://blog.ashchan.com/archive/2011/08/21/learn-ruby-on-rails/
LikeLike
Good to now that it works for you. =D
LikeLike
Anyone manage to get this working using omniauth.origin?
https://github.com/plataformatec/devise/wiki/How-To:-redirect-to-a-specific-page-on-successful-sign-in
LikeLike
Allan did make it work. you can refer to this comment.
LikeLike