Can't verify CSRF token authenticity Rails/React
Asked Answered
K

4

11

I have a react component in my rails app where I'm trying to use fetch() to send a POST to my rails app hosted on localhost, this gives me the error:

ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):

I'm using devise gem to handle user/registrations and logins.

I have tried to remove protect_from_forgery with: :exception

Here is the code for my fetch,

this.state.ids.sub_id});
  fetch(POST_PATH, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: body  
  }).then(res => res.json()).then(console.log);

How can I get the csrf token and send it through the form so that it will pass?
Ideally I would like to just send it through the headers but I have no idea how to access the token.

Kenogenesis answered 21/2, 2019 at 13:18 Comment(0)
I
21

The simplest way to do this, if you are merely embedding a react component in your Rails view, is to retrieve the csrf token from your rails view and then pass it as a header in your fetch api call.

You can get the csrf token by doing something like this:

const csrf = document.querySelector("meta[name='csrf-token']").getAttribute("content");

And then you just pass it as a header in your fetch call: ... headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': csrf }, ...

I normally don't use fetch, so not too sure about the exact syntax, but this should help guide you.

Imprimis answered 21/2, 2019 at 13:43 Comment(1)
But don't they now have per form csrf tokens in rails 5 and later? Does this still work with that?Jubbulpore
K
3

Thanks! I ended up with this as a working solution: In the view that renders my react component

<% csrf_token = form_authenticity_token %>

<%= react_component('ExerciseDisplay', {
  program: @program.subprograms.first.exercises, ids: {sub_id: @program.subprograms.first.id, team_id: @team.id, token: csrf_token}
}) %>

I passed the token into state, then accessed it via fetch:

  fetch(POST_PATH, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-CSRF-Token': this.state.ids.token
      },
      body: body  
}).then(res => res.json()).then(console.log);
Kenogenesis answered 21/2, 2019 at 14:59 Comment(0)
C
0

Inside your form element, add a authenticity_token:

<input type="hidden" name="authenticity_token" value={csrf}/>

Set the value as per the below:

const csrf = document.querySelector("meta[name='csrf-token']").getAttribute("content");
Component answered 12/2, 2023 at 4:55 Comment(0)
A
-2

I too faced the same issue when using rails 5.2 and i was able to fix this issue by adding

protect_from_forgery with: :null_session in application_controller.rb i got this from here,please refer this

Anglophile answered 6/5, 2019 at 19:23 Comment(2)
This seems like a security risk doesnt it?Belshin
@SamuelFaure i am not an expert in this maybe ur right,please refer the link attachedAnglophile

© 2022 - 2024 — McMap. All rights reserved.