1

Context: a Rails app in production, hosted on Heroku, that has around 800 users.

  • Ruby 2.4.2
  • Rails 5.1.4
  • Devise 4.3.0

For some reason, I have seen a few users experience an error:

ActionController::InvalidAuthenticityToken

[GEM_ROOT]/gems/actionpack-5.1.4/lib/action_controller/metal/request_forgery_protection.rb:195

For requests to POST /students/:id/registrations.

It is intermittent, and very few users experience the error.

Clients are Safari 11.0 on iPads.

ApplicationController:

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :authenticate_user!, unless: :devise_controller?
  before_action :restrict_from_students, unless: :devise_controller?
  # ...
end

RegistrationsController:

class RegistrationsController < ApplicationController
  skip_before_action :restrict_from_students, only: :create
  # ...
end

Is there some scenario (re-POSTing the request, auth timeout but submitting, lack of JS) that would cause this? I cannot seem to reproduce it.

ybakos
  • 8,152
  • 7
  • 46
  • 74
  • Its super hard to help if you cannot reproduce yourself, are you setting the csrf token in a hidden form field, or a meta tag in your html head? – JP Silvashy Apr 17 '18 at 20:44
  • 1
    @JPSilvashy thank you. I think I've finally reproduced the error. It's the session timeout, with app ui still visible, and user sending a POST. I'll add the answer. – ybakos Apr 17 '18 at 20:49

2 Answers2

2

I was having a similar issue.

Use rescue_from in the application controller and redirect somewhere useful with a notification. In my case I attempt to redirect the user back to where they were to reattempt their action, or to the home page as a fallback.

Example for rails 5:

class ApplicationController < ActionController::Base
  rescue_from ActionController::InvalidAuthenticityToken, 
    with: :handle_invalid_token


  def handle_invalid_token
    redirect_back fallback_location: root_path, 
      notice: 'Stale session detected'
  end
end
Somazx
  • 532
  • 2
  • 18
1

Thanks to the rubber duck, I have reproduced the issue.

  1. Sign out
  2. Go "back" to the cached app UI.
  3. Click the button to generate a POST request.
  4. Observe the exception.

The solution here is to use rescue_from to likely redirect the user to the sign in page.

Thank you rubber duckie!

ybakos
  • 8,152
  • 7
  • 46
  • 74
  • 1
    Lemme guess! you may also be using turbolinks? I think if that is the case, there may be some gotcha's with your back button as well. – JP Silvashy Apr 17 '18 at 21:48