devise: Rails 7: logout redirect not working
Set this in application_controller.rb:
def after_sign_out_path_for scope
root_path
end
You expect the logout to redirect the user to root.
However Devise returns a redirect with status 302, which does not work with Turbo.
All redirects must return 303 (i.e. status: :see_other) in order to work with Turbo.
This should be fixed in Devise in order to work with Rails 7.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 12
- Comments: 31 (3 by maintainers)
Commits related to this issue
- Reinstate link_to with delete method for Devise sign out. The redirect needs to be 303 for Turbo. https://github.com/heartcombo/devise/issues/5458#issuecomment-1235991534 — committed to ApprenticeshipStandardsDotOrg/ApprenticeshipStandardsDotOrg by littleforest 2 years ago
- Reinstate link_to with delete method for Devise sign out. The redirect needs to be 303 for Turbo. https://github.com/heartcombo/devise/issues/5458#issuecomment-1235991534 — committed to ApprenticeshipStandardsDotOrg/ApprenticeshipStandardsDotOrg by littleforest 2 years ago
- Reinstate link_to with delete method for Devise sign out. The redirect needs to be 303 for Turbo. https://github.com/heartcombo/devise/issues/5458#issuecomment-1235991534 — committed to ApprenticeshipStandardsDotOrg/ApprenticeshipStandardsDotOrg by littleforest 2 years ago
- Fixed logout link and redirection This was related to the move to turbo. See: https://github.com/heartcombo/devise/issues/5458 Refactored some of application.html.erb to a partial while I'm at it. — committed to xronos-ch/xronos.rails by joeroe a year ago
- Integrate with Hotwire/Turbo by configuring error and response statuses Treat `:turbo_stream` request format as a navigational format, much like HTML, so Devise/responders can work properly. Allow c... — committed to heartcombo/devise by carlosantoniodasilva a year ago
- Integrate with Hotwire/Turbo by configuring error and response statuses Treat `:turbo_stream` request format as a navigational format, much like HTML, so Devise/responders can work properly. Allow c... — committed to heartcombo/devise by carlosantoniodasilva a year ago
- Integrate with Hotwire/Turbo by configuring error and response statuses Treat `:turbo_stream` request format as a navigational format, much like HTML, so Devise/responders can work properly. Allow c... — committed to heartcombo/devise by carlosantoniodasilva a year ago
- Integrate with Hotwire/Turbo by configuring error and response statuses Treat `:turbo_stream` request format as a navigational format, much like HTML, so Devise/responders can work properly. Allow c... — committed to heartcombo/devise by carlosantoniodasilva a year ago
You have to change from:
<%= link_to “Sign out”, destroy_user_session_path, method: delete %>
to
<%= link_to “Sign out”, destroy_user_session_path, data: { turbo_method: :delete" } %>
I fixed this as follows:
This worked for me initially:
But after making these turbo changes (to fix an unrelated issue of some bootstrap javascripts not working) from:
to this
then logout broke.
However, this worked:
Hope it’s useful.
@designium Yes, sure, I already use the correct code for Turbo… However there is the bug described in the original post.
I ended up with this which makes a mini form:
This issue is not specific to Turbo, it’s how the Fetch API behaves: when the HTTP status is 302, the browser will send another request to the redirect URL using the same HTTP method as the initial request. Turbo wraps the Fetch API, but I ran into the same issue in our app which doesn’t use Turbo.
In our case we solved this by changing the HTTP method for the sign out route from DELETE to GET.
In
config/initializers/devise.rb:Then you can use a regular link in your view, no Turbo/JS needed at all:
Alternatively, you can keep using a DELETE route (preferable, since GET routes with side-effects are kind of icky) and use a form rather than a link:
This also requires no Turbo/JS, though you’ll probably want to sprinkle some CSS to make the button look like a regular link.
@collimarco I have found simple hotfix
You just need add
status: :see_other(303) toredirect_tomethod arguments to make it works correctlyI just notice that when you are using a button to log out:
<%= button_to "Log Out", destroy_user_session_path, method: :delete %>the the redirect works as expected and the user is taken to the root_path. However as soon as you are using a link things are not working (mostly due to the status issue mentioned above).@Havoc85
You need to generate or create an inherited Devise controller for sessions first. You can do that by running the following command (assuming that “user” is your Devise model):
Uncomment the
destroymethod in the new file that gets created and place the above code inside the method.Don’t forget to update your Devise routes for the changes to take effect.
Disabling Turbo is the wrong answer here. This issue is specific to an incorrect redirect being returned by Devise::SessionController.
My Selenium tests fail like this:
The Rails log will follow a pattern similar to this:
The issue is that Turbo is attempting to render
after_sign_out_pathwith the incorrect HTTP Verb (DELETE, in this case). You want your Devise controller to respond with HTTP 303 See Other. Solutions that override Devise’s default behavior, such as @mattbrictson’s, should be used.Don’t forget to update your routes, too:
None of the other replies actually fix the OP’s original issue.
The main branch should contain all that’s necessary for fully working with Turbo now, which should fix this. A new version will be released soon, but feel free to test it out from the main branch in the meantime, and report back on any issues. Thanks.
👍 Thanks
Thank you for that description! That helps a lot.