Stimulus Discourse

CSRF token InvalidAuthenticityToken


#1

I tried to use a fetch(… method: ‘PUT’) and I’m getting an InvalidAuthenticityToken error. I’m guessing this has something to do with the csrf token. Has anyone fixed this problem ?


#2

Are you using the jquery_ujs or the rails_ujs gem?

In my application I’m using jquery_ujs and haven’t had any issues with authenticity tokens.


#3

You can query your <meta name="csrf-token"> element for the token and include it in the request’s headers:

fetch(…, {
  method: "PUT",
  credentials: "same-origin",
  headers: {
    "X-CSRF-Token": getMetaValue("csrf-token")
  },
  …
})

function getMetaValue(name) {
  const element = document.head.querySelector(`meta[name="${name}"]`)
  return element.getAttribute("content")
}

#4

That’s what I ended up doing. I wasn’t sure if that was the best practices.
What was curious though…
document.querySelector(meta[name="${name}"]).content #=> worked
however;
$(meta[name="${name}"]).content #=> didn’t work work in a debugger in the stimulus controller. If I let the page finish loading, it does work :confused:


#5

@scottharvey I’m using the gem, but stimulus is in webpack… so those don’t crossover do they ?


#6

jquery_ujs has installation instructions for webpack so it should work but I haven’t tried using Webpack.


#7

Just to add my 2 cents to this thread, in a Rails app you can also use Rails-ujs ajax function. It is my understanding that it automatically includes the CSRF token for you.

As an example here is what I have been using in an app:

const data = new FormData();
data.append("myModelName[field]", value);

Rails.ajax({
  url: "/my_post_url",
  type: "POST",
  data
});

#8

I have fixed this in the past using the rails-ujs module:

import { Controller } from 'stimulus'
import Rails from 'rails-ujs'

export default class extends Controller {
  connect() {
    fetch('/some/url', {
      method: 'PUT',
      credentials: 'same-origin',
      headers: { 'X-CSRF_Token': Rails.csrfToken() }
    })
  }
}