-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rails 7: logout redirect not working #5458
Comments
Not only the redirect for logout, but also the other redirects should use the status 303 in order to work with Turbo. (The only other alternative would be to make Turbo accept the 302, but from the related issue linked above it seems that Rails team won't fix that) |
Also note that by using 302, after logout response, you also get an "extra" DELETE request to root path, which results in a 404. This is quite scary, since you get an unexpected DELETE request on random path! |
I think this is related to #5453 While the PR isn't merged I would just disable turbo on devise views |
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" } %> |
@designium Yes, sure, I already use the correct code for Turbo... However there is the bug described in the original post. |
@collimarco I have found simple hotfix # app/controllers/sessions_controller.rb
class SessionsController < Devise::SessionsController
def respond_to_on_destroy
respond_to do |format|
format.all { head :no_content }
format.any(*navigational_formats) { redirect_to after_sign_out_path_for(resource_name), status: :see_other}
end
end
end # config/routes.rb
Rails.application.routes.draw do
# ...
devise_for :users, controllers: { sessions: 'sessions' }
# ...
end You just need add |
I fixed this as follows: <%= link_to("Log out", destroy_user_session_path, method: :delete, data: { turbo_method: :delete }) %> module Users
class SessionsController < Devise::SessionsController
def destroy
super do
# Turbo requires redirects be :see_other (303); so override Devise default (302)
return redirect_to after_sign_out_path_for(resource_name), status: :see_other
end
end
end
end |
@mattbrictson you can also add return redirect_to after_sign_out_path_for(resource_name), status: :see_other, notice: I18n.t('devise.sessions.signed_out') |
I just notice that when you are using a button to log out: |
Also, overriding the |
any news? |
nope... |
This worked for me initially:
But after making these turbo changes (to fix an unrelated issue of some bootstrap javascripts not working) from: // app/javascript/application.js
import "@hotwired/turbo-rails" to this // app/javascript/application.js
import { Turbo } from "@hotwired/turbo-rails"
Turbo.session.drive = false then logout broke. However, this worked:
Hope it's useful. |
I ended up with this which makes a mini form:
|
It works for me |
Looking at the patch by @mattbrictson I see it looks really similar to the PR here #5410 |
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
Don't forget to update your routes, too: devise_for :users, controllers: {
sessions: 'users/sessions'
} None of the other replies actually fix the OP's original issue. |
I'm sorry, can anyone - maybe @mattbrictson or @danielricecodes - tell me, where to put that? Thanks in advance. |
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 # The default HTTP method used to sign out a resource. Default is :delete.
config.sign_out_via = :get Then you can use a regular link in your view, no Turbo/JS needed at all: <%= link_to "Sign Out", destroy_user_session_path %> 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: <%= button_to "Sign Out", destroy_user_session_path, method: :delete %> This also requires no Turbo/JS, though you'll probably want to sprinkle some CSS to make the button look like a regular link. |
@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 Don't forget to update your Devise routes for the changes to take effect. |
Thank you for that description! That helps a lot. |
I followed all the instruction and still face with the actionController::RoutingError (No route matches [GET] "/users/sign_out"): Not sure if there is anyway to find the root cause ***solved just because changing to the correct resource_name |
👍 Thanks |
sign out. The redirect needs to be 303 for Turbo. heartcombo/devise#5458 (comment)
sign out. The redirect needs to be 303 for Turbo. heartcombo/devise#5458 (comment)
sign out. The redirect needs to be 303 for Turbo. heartcombo/devise#5458 (comment)
Not a correct way because we want to use turbo |
My solution:
|
This was related to the move to turbo. See: heartcombo/devise#5458 Refactored some of application.html.erb to a partial while I'm at it.
Treat `:turbo_stream` request format as a navigational format, much like HTML, so Devise/responders can work properly. Allow configuring the `error_status` and `redirect_status` using the latest responders features, via a new custom Devise responder, so we can customize the both responses to match Hotwire/Turbo behavior, for example with `422 Unprocessable Entity` and `303 See Other`, respectively. The defaults aren't changing in Devise itself (yet), so it still responds on errors cases with `200 OK`, and redirects on non-GET requests with `302 Found`, but new apps are generated with the new statuses and existing apps can opt-in. Please note that these defaults might change in a future release of Devise. PRs/Issues references: #5545 #5529 #5516 #5499 #5487 #5467 #5440 #5410 #5340 #5542 #5530 #5519 #5513 #5478 #5468 #5463 #5458 #5448 #5446 #5439
Treat `:turbo_stream` request format as a navigational format, much like HTML, so Devise/responders can work properly. Allow configuring the `error_status` and `redirect_status` using the latest responders features, via a new custom Devise responder, so we can customize the both responses to match Hotwire/Turbo behavior, for example with `422 Unprocessable Entity` and `303 See Other`, respectively. The defaults aren't changing in Devise itself (yet), so it still responds on errors cases with `200 OK`, and redirects on non-GET requests with `302 Found`, but new apps are generated with the new statuses and existing apps can opt-in. Please note that these defaults might change in a future release of Devise. PRs/Issues references: #5545 #5529 #5516 #5499 #5487 #5467 #5440 #5410 #5340 #5542 #5530 #5519 #5513 #5478 #5468 #5463 #5458 #5448 #5446 #5439
Treat `:turbo_stream` request format as a navigational format, much like HTML, so Devise/responders can work properly. Allow configuring the `error_status` and `redirect_status` using the latest responders features, via a new custom Devise responder, so we can customize the both responses to match Hotwire/Turbo behavior, for example with `422 Unprocessable Entity` and `303 See Other`, respectively. The defaults aren't changing in Devise itself (yet), so it still responds on errors cases with `200 OK`, and redirects on non-GET requests with `302 Found`, but new apps are generated with the new statuses and existing apps can opt-in. Please note that these defaults might change in a future release of Devise. PRs/Issues references: #5545 #5529 #5516 #5499 #5487 #5467 #5440 #5410 #5340 #5542 #5530 #5519 #5513 #5478 #5468 #5463 #5458 #5448 #5446 #5439
Treat `:turbo_stream` request format as a navigational format, much like HTML, so Devise/responders can work properly. Allow configuring the `error_status` and `redirect_status` using the latest responders features, via a new custom Devise responder, so we can customize the both responses to match Hotwire/Turbo behavior, for example with `422 Unprocessable Entity` and `303 See Other`, respectively. The defaults aren't changing in Devise itself (yet), so it still responds on errors cases with `200 OK`, and redirects on non-GET requests with `302 Found`, but new apps are generated with the new statuses and existing apps can opt-in. Please note that these defaults might change in a future release of Devise. PRs/Issues references: #5545 #5529 #5516 #5499 #5487 #5467 #5440 #5410 #5340 #5542 #5530 #5519 #5513 #5478 #5468 #5463 #5458 #5448 #5446 #5439
However, I ended up using @revskill10 's solution as I wanted use a |
Hey, you're all welcome to try this new branch and see if that works for you out of the box: #5548. Please see the description on how to get things setup, and report back if you run into any issues. Thanks. |
Using the first line of codes works perfectly for me! Thank you! I highly recommend everyone to have a try. |
Setting |
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. |
typo data: { turbo_method: :"delete" } |
I just started working on Rails 7 app and experienced same issue. My issue was login and logout works. It just renders the new page at the bottom of the login page instead of redirecting. I was able to fix by: For login button: |
Set this in
application_controller.rb
: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.
Related: rails/rails#44170
The text was updated successfully, but these errors were encountered: