Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated CSRF tokens not sent when forms inserted by javascript or Turbolinks #456

Open
travisp opened this issue Feb 8, 2016 · 4 comments

Comments

@travisp
Copy link

travisp commented Feb 8, 2016

Example issue:

  1. A page is utilizing fragment caching and is caching a non-remote form (perhaps a Contact Us form that is always in the "new" state)

  2. The user navigates to that page using turbolinks.

  3. The user submits the form on that page and then receives a CSRF token validation error

I think it could be argued that this is not a concern of jquery-ujs, but jquery-ujs does attempt to solve the issue of cached non-remote forms. jquery-ujs currently calls rails.refreshCSRFTokens() on initial page load, where it goes through each form (including non-remote forms) on the page and updates all of the csrf param elements with the current token value from the header. The comment in the source code says:

Make sure that all forms have actual up-to-date tokens (cached forms contain old ones)

This works unless the page is loaded by turbolinks (neither turbolinks nor jquery-ujs will update the cached csrf token), or is otherwise updated by javascript (for example, a js.erb response that inserts a cached form into the current page).

I think there are a couple of ways jquery-ujs could handle this (for example, calling refreshCSRFTokens() on form submit), unless it seems more appropriate as an update to Turbolinks and manual usage of refreshCSRFTokens in applications updating forms with javascript. Given that both turbolinks and using js.erb to update pages are fairly standard ways for rails developers to update the page, I think it could be helpful if jquery-ujs could better handle forms that are cached.

Would a PR be welcome for this in jquery-ujs?

@bluehallu
Copy link

+1

This on main application.js solves it in the meanwhile:

$(document).on('page:load', function(){
    $.rails.refreshCSRFTokens();
});

@raldred
Copy link

raldred commented May 24, 2017

Just been bitten by this using Rails 5.0.2. @bluehallu's suggestion seems to resolve it.
This feels like really basic usage of Rails & forms, I'm surprised it's not been resolved.

@winterblack
Copy link

what the heck is .on('page:load')? I can't find documentation for it anywhere, and it never fires for me.

@Ex-Ark
Copy link

Ex-Ark commented Apr 8, 2019

According to this SO answer , since Rails 5 it is now turbolinks:load , but it's not firing either for me. Tokens are still invalid .

Edit: The $(document).on('turbolinks:load', function(){ does work, I didn't check a dumb mistake in my application.js file
Check you have jquery as well as jquery_ujs (for $.rails) imported before declaring this.

//= require jquery
//= require jquery_ujs

$(document).on('turbolinks:load', function(){
   $.rails.refreshCSRFTokens();
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants