jeudi 20 décembre 2018

Rails can't verify CSRF token authenticity after long idle

I have a Rails app and I'm using devise with timeoutable. If the user's computer is left idle for some time (about an hour I think), I get the following server logs:

Processing by Api::SessionsController#create as JSON
Parameters: {"email"=>"xxx@xxx.xxx", "password"=>"[FILTERED]"}
WARNING: Can't verify CSRF token authenticity
...
Completed 200 OK in 553ms (Views: 462.6ms | Solr: 0.0ms)
Started GET "/api/home" for ::ffff:150.129.131.50 at 2018-12-20 12:18:51 +0000
Processing by Api::HomeController#show as JSON
Completed 401 Unauthorized in 1ms

The CSRF token is normally working fine, the issue only occurs after an hour or so. This has the effect of logging the user out as soon as they log in. Here is the relevant code:

application_controller.rb

    protect_from_forgery
    before_filter :authenticate_user!

application.html.erb

    <%= csrf_meta_tags %>

application.js

    //= require jquery
    //= require jquery_ujs

sessions_controller.rb

    skip_before_filter :authenticate_user!

I am using the devise gem with timeoutable. This is also a single page app that uses Ajax requests to access an API, and the session cookie for user sessions. But I don't actually see how that's relevant anyway, since any web page would need to be able to handle an expired CSRF token somehow, and for whatever reason I'm not finding the solution.

It's also probably worth mentioning that changing the timeout_in to be very short, like 30 seconds, doesn't reproduce this error, and neither does changing the computer's sleep timer to 1 minute. Which makes sense given that it's the CSRF token that's expiring, not the user session.

Ruby v1.9.3

Rails v3.2.8

Devise v3.2.4

Unicorn v4.8.2

Aucun commentaire:

Enregistrer un commentaire