Hi I am using Devise for my user authentication suddenly my new user registration was not working.
this was error I am getting.
ActionController::In
If you've tried all the remedies on this page and you're still having an issue with InvalidAuthenticityToken exceptions, it may be related to the browser caching HTML. There's an issue on Github with 100s of comments along with some reproducible code. In a nutshell, here's what was happening to me as it relates to HTML caching:
config/initializers/session_store.rb for config options. This session cookie stores useful information, including a CSRF token that is used to decrypt and validate the authenticity of the request. Important: By default, the session cookie will expire when the browser window closes. verified_request? method in Rails 4.2+. Many browsers are now implementing HTML caching, so that when you open a page the HTML is loaded without a request. Unfortunately, when the browser is closed the session cookie is destroyed, so if the user closes the browser while on a form (such as a login page), then the first request will not contain a CSRF token thus throwing an InvalidAuthenticityError.
As noted in this Github comment, Django takes this approach:
Django puts adds the token in its own cookie called CSRF_COOKIE. This is a persistent cookie that expires in a year. If subsequent requests are made, the cookie's expiry is updated.
In Rails:
# config/initializers/session_store.rb
Rails.application.config.session_store :cookie_store, expire_after: 14.days
With many things security related, there's concern that this could create vulnerabilities, but I have not been able to locate any examples of how an attacker could exploit this.
This approach involves setting a separate token that can be read by the browser, and if that token is not present, refreshing the page. Thus, when the browser loads the cached HTML (without the session cookie), executes the JS on the page, the user can be redirected or refresh the HTML.
For example, setting a cookie for each non-protected request:
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
after_action :set_csrf_token
def set_csrf_token
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
end
end
Checking for this cookie in JS:
const hasCrossSiteReferenceToken = () => document.cookie.indexOf('XSRF-TOKEN') > -1;
if (!hasCrossSiteReferenceToken()) {
location.reload();
}
This will force the browser to refresh.
I hope this helps some folks out there; this bug cost me days of work. If you're still having issues, consider reading up on:
prepend: true bug in Devise, well described here.