I only get this error when I manually enter the URL into the browser. If i click the "sign out" link on my site, it logs the user out fine. This is my "sign out" link:
<%= link_to "Sign out", destroy_user_session_path, method: :delete %>
which works perfect. How can I get the sign out functionality working if the user types the address into the address bar? I know it has to do with GET and DELETE requests. It is using a DELETE request with the link, but using a GET request when the URL is manually entered. How can I fix this?
Adding;
devise_scope :user do
get '/users/sign_out' => 'devise/sessions#destroy'
end
to the Routes fixed my issue.
Basically,
When you try to type url manually or you try to clickin link "sign-out" with new tab there are HTTP GET request and you will get No route matches [GET] "/users/sign_out"
, it doesn't exist because you have only via DELETE
request for /users/sign_out
on your routes.rb
, for the solution you can add this in config/initializer/devise.rb
# The default HTTP method used to sign out a resource. Default is :delete.
config.sign_out_via = Rails.env.test? ? :get : :delete
And change DELETE
to MATCH
request on your routes.rb
e.g : match 'users/sign_out' => "devise/sessions#destroy"
For reference : Devise for user management and authentication.
To be honest, supposed change the default 'delete' HTTP method it is not recommended. It's to user for test (e.g using cucumber) Cucumber Testing for “Sign Out”
Jose Valim explained why: “GET requests should not change the state of the server. When sign out is a GET request, CSRF can be used to sign you out automatically and things that preload links can eventually sign you out by mistake as well.”
@manoj mona's say 'we must not let the user to sign out by typing in the URL. It is a bad practice'
So, If user to sign out by type in the URL.
You can to define it, if get request it will redirect or render notice (like stackoverflow sign out)
Or don't use link_to
tag for sign out, use input
tag with form (like facebook sign out), so users can't type in the URL see this answer
Modify devise.rb
to
config.sign_out_via = :get
And change the link
<%= link_to "log out", destroy_user_session_path, method: :get %>
Add this to application.js
:
//= require jquery_ujs
I have no idea what is the reason (i'm new to ruby on rails), but once you add this line to you applicaiton layout your problem will be solved,
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
and keep the logout link as follows
<%= link_to "Sign Out", destroy_user_session_path, :method => :delete %>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With