3

I just did an initial deploy to Heroku of a Rails 4 app that uses Devise for authentication. Signing out works locally, but Heroku returns an error that "The page you were looking for does not exist," and it doesn't log the user out.

Based on the Heroku logs and a Google/SO search, it looks like the reason is that Heroku is using a GET request instead of DELETE - though my app code specifies the :delete method for the link, and Devise uses DELETE for signing out by default. Some articles suggested that Heroku uses GET so that users can sign out without having JavaScript enabled, but I have the JS include tag in my code and JS is enabled in my browser. (I've checked using both Chrome and Safari.)

I've found instructions for changing the configuration so that Devise uses :get instead of :delete, but I would prefer to use the more secure :delete method if at all possible.

Thanks for the ideas so far. In response to your questions:

Here is my link:

<%= link_to "Log out", destroy_admin_session_path, method: :delete %>

This is what I have in the head tag to load the javascript:

  <%= javascript_include_tag "application", "data-turbolinks-track" => true %>

There are no JS errors reported in the console.

Taylor714
  • 2,876
  • 1
  • 15
  • 16
  • 3
    can we see the code for logout link you are using..? – neo-code Apr 15 '14 at 05:02
  • I agree with @Maynank, it is difficult to determine how to advise without seeing the code. I am using `<%= link_to 'Log out', destroy_user_session_path, :method => :delete %>`, without any problems on Heroku. – Thomas Apr 15 '14 at 05:54
  • If you have any Javascript errors on your page, or are not loading Rails' Javascript helpers, a delete link won't work. – sevenseacat Apr 15 '14 at 06:58

2 Answers2

3

I found the solution. The problem is that Rails 4 handles assets differently than Rails 3. By default, Rails 4 doesn't serve static assets. You can manually change this in config/application.rb by setting:

config.serve_static_assets = true

Another option (and the one that Heroku recommends) is to use the rails_12factor gem. Adding this to your Gemfile and running bundle install will make the adjustment for you and also set your logger to standard out. It can be used with Rails 3 and Rails 4 both.

gem 'rails_12factor', group: :production

I opted to use the gem. After I ran bundle install, committed the changes, and redeployed - my sign out link worked fine with no need to change the method. My scss files were also compiled and implemented accurately after this. (I hadn't done anything with the styles before, so I didn't realize this was an issue. Funny how encountering a new problem can help lead to a solution...)

Here are the resources that helped me:

https://devcenter.heroku.com/articles/rails-4-asset-pipeline

https://github.com/heroku/rails_12factor

Taylor714
  • 2,876
  • 1
  • 15
  • 16
0

You can't get more secure than the delete method currently

Rails actually has to set delete with JS, as it's not supported by most browsers. The way you set it is as thus:

<%= link_to "Logout", user_session_destroy_path, method: :delete %>

Although I get your point about making it more secure, I think your focus should be on how the authentication is processed on the backend. Sending requests is only a front-end concern; handling them is the realm of Rails

Richard Peck
  • 76,116
  • 9
  • 93
  • 147
  • BTW checking with `Chrome & Safari` does not give the best representation of browsers, as they both run using the `webkit` engine. You'd be best testing with `Firefox`, `IE` & `Chrome` / `Safari` – Richard Peck Apr 15 '14 at 06:40
  • The :delete method is the one I would like to use. :) I've edited my original post to show the code for the link. It's essentially the same as yours except with "admin" instead of "user" (to match my model name.) Good point about browsers. I checked Firefox with the same result. – Taylor714 Apr 15 '14 at 22:10
  • Thanks for answer - are you saying your link doesn't work with `delete`? – Richard Peck Apr 16 '14 at 08:09
  • 2
    That's correct. Heroku is still using a GET request and returning an error because there's no route that matches. – Taylor714 Apr 16 '14 at 18:06