Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails Devise Error "No route matches [GET] "/users/sign_out""

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?

like image 311
theDazzler Avatar asked Jan 10 '14 09:01

theDazzler


5 Answers

Adding;

devise_scope :user do get '/users/sign_out' => 'devise/sessions#destroy' end

to the Routes fixed my issue.

like image 67
Quaso Avatar answered Nov 20 '22 00:11

Quaso


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.

  1. You can to define it, if get request it will redirect or render notice (like stackoverflow sign out)

  2. 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

like image 41
rails_id Avatar answered Nov 19 '22 23:11

rails_id


Modify devise.rb to

config.sign_out_via = :get

And change the link

<%= link_to "log out", destroy_user_session_path, method: :get %>
like image 32
lalameat Avatar answered Nov 19 '22 22:11

lalameat


Add this to application.js:

//= require jquery_ujs 
like image 4
vimesh Avatar answered Nov 19 '22 22:11

vimesh


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 %>
like image 2
Tareq Marmash Avatar answered Nov 19 '22 22:11

Tareq Marmash