1

Scenario is this: User has 2 windows on which s/he is logged in. S/he logs out of one, stays logged in on the other, and then on the latter, triggers some action, say a form submission.

Initially, what happened is that it threw a invalid authenticity token error. I've updated the protect_from_forgery in ApplicationController to be with: :null_session so that instead of the Exception it throws a 401.

Great! Now for step 2, rather than the user just seeing a line of text saying You need to sign in or sign up before continuing., I'd like to redirect him/her back to the sign in page.

This is where I'm having problems... I've been reading this guide: http://agileleague.com/blog/rails-3-2-custom-error-pages-the-exceptions_app-and-testing-with-capybara/ which says that 401 errors are not default caught by rails. The guide has two lines of code that will define it and catch it, and then one line of code in the route that will make the routing work. Basically it looks like this:

# add to app/controllers/application_controller.rb
class UnauthorizedException < Exception; end

# add to app/config/application.rb
config.action_dispatch.rescue_responses.merge!('ApplicationController::UnauthorizedException' => :unauthorized)

# add to routes (in my case this is what I've done for Devise)
devise_scope :user do
  match '/401', to: 'users/sessions#new', type: "401", via: :get
end

Now I'm very green at Exceptions handling, but that looks incomplete to me... and it is not working either. If I navigate to /401 in my local server I do get taken to the sign in page so great, the routing works. But if I replicate the scenario outlined above that leads to the 401 in the first place, rather than being redirected, I still am just left with a page that has a single line of plain text.

Help?

james
  • 3,989
  • 8
  • 47
  • 102
  • If you are using `before_action :authenticate_user!` than Devise should automatically redirect to the sign in path. This will happen before rails tries to evaluate the CSRF token which should be invalid since the session should has just been reset. This sounds like you are doing something skrewy and have fixated the session. – max Jul 12 '15 at 03:37
  • hmm.... I am using `before_action :authenticate_user!`... where might I have gone wrong? – james Jul 12 '15 at 07:39
  • put it another way, is there a method you think where I can force the order of the before filters ? – james Jul 12 '15 at 07:46
  • http://stackoverflow.com/questions/18582400/what-order-do-before-filters-occur-in – max Jul 12 '15 at 07:58
  • Thanks @max. Wondering if you'll have more good ideas for me... I read through a bunch of SO, and then started by trying to figure out the order of my current `filter_chain`. Using this code: http://makandracards.com/makandra/10923-how-to-inspect-controller-filter-chains-in-specs on how to inspect the controller `filter_chain`, I've determined that the order is (for 2 custom controllers) 1) `verify_authenticity_token`, 2) `set_xhr_redirected_to`, 3) `set_request_method_cookie`. In other words, there's no `authenticate_user!`. Yet in only one of the controllers do I have this problem. Thoughts? – james Jul 12 '15 at 17:57
  • Try `prepend_before_action :authenticate_user!` to try to push it the front of filter chain - you want Devise to redirect before Rails tries to verify the CSRF token. – max Jul 12 '15 at 18:01
  • Sorry @max you responded before I had a chance to edit my comment: the `authenticate_user!` was present, I just missed it in the list, and `prepend` does successfully push it to the front. Now when I inspect the `filter_chain` in the console, `authenticate_user!` is indeed first. But in local server when I test; it's still last and the problem persists! Also to note, I have 2 custom controllers; only in one is this a problem; in the other, I have no prepend, in console `authenticate_user!` appears last, but it works fine – james Jul 12 '15 at 18:08

0 Answers0