React with Rails 5 getting CSRF error for post with axioms

I am trying to use react_on_rails

to build my first react and rails example. I am trying to store some data in a rails backend using axios for ajax.

here's my code:

import store from "../store/helloWorld";
import axios from "axios";

export const SAVE_NAME = "SAVE_NAME";

export function saveNameAction(name) {
  return {
    type: SAVE_NAME,
    name
  };
}

export function saveName(name) {
  axios
    .post("/hello_world", saveNameAction(name))
    .then(function(response) {
      console.log(response);
    })
    .catch(function(error) {
      console.log(error);
    });
}

      

and component:

import PropTypes from "prop-types";
import React from "react";
import * as actions from "../actions/helloWorld";

export default class HelloWorld extends React.Component {
  static propTypes = {
    name: PropTypes.string.isRequired // this is passed from the Rails view
  };

  /**
   * @param props - Comes from your rails view.
   */
  constructor(props) {
    super(props);
    this.state = { name: this.props.name };
  }

  updateName(name) {
    this.setState({ name: name });
  }

  handleSubmit(event) {
    event.preventDefault();
    actions.saveName(this.state.name);
  }

  render() {
    return (
      <div>
        <h3>
          Hellopp, {this.state.name}!
        </h3>
        <hr />
        <form>
          <label htmlFor="name">Say hello to:</label>
          <input
            id="name"
            type="text"
            value={this.state.name}
            onChange={e => this.updateName(e.target.value)}
          />

          <input
            type="submit"
            value="Submit"
            onClick={event => this.handleSubmit(event)}
          />
        </form>
      </div>
    );
  }
}

      

The problem is when I click submit button my backend reports

Started POST "/hello_world" for ::1 at 2017-07-07 15:30:44 +0200
Processing by HelloWorldController#create as HTML
  Parameters: {"type"=>"SAVE_NAME", "name"=>"Stranger", "hello_world"=>{"type"=>"SAVE_NAME", "name"=>"Stranger"}}
Can't verify CSRF token authenticity.
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)

ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):

      

First, I don't understand why the parameters seem to be passed twice, but that don't even generate a warning, so now don't worry.

The problem is I don't see a way to get CSRF tokens in my react code to use in requests post

Should I turn off CSRF? or is there a better way?

+3


source to share


3 answers


ActionController :: InvalidAuthenticityToken (ActionController :: InvalidAuthenticityToken):



Rails handles CSRF attacks by adding Non-GETs (POST, PUT / PATCH, and DELETE) authenticity_token

to every request . The error means that you are not passing in the request parameters, you must add a unique to , something like that should fix the problem.authencity_token

authenticity_token

params

"authuenticity_token" => "BsfdgtZ1hshxgthjj"

0


source


I found I react_on_rails

have a helper system for handling CSRF tokens,

it mainly uses:

  <%= csrf_meta_tags %>

      

to add csrf_token to headers on the page as meta



and then you can use:

import ReactOnRails from "react-on-rails";

export function saveNameAction(name) {
  console.log("creating action " + name);
  return {
    authenticity_token: ReactOnRails.authenticityToken(),
    type: SAVE_NAME,
    name
  };
}

      

to extract it and use it.

0


source


react_on_rails

handles this problem by providing two helpers. From the react_on_rails

documentation :

Rails has built-in security for the cross-site request framing (CSRF) routine, see the Rails Documentation. To make good use of this feature in JavaScript requests, React on Rails provides two helpers that can be used like the following for POST, PUT, or DELETE requests:

import ReactOnRails from 'react-on-rails';

// reads from DOM csrf token generated by Rails in <%= csrf_meta_tags %>
csrfToken = ReactOnRails.authenticityToken();

// compose Rails specific request header as following { X-CSRF-Token: csrfToken, X-Requested-With: XMLHttpRequest }
header = ReactOnRails.authenticityHeaders(otherHeader);

      

0


source







All Articles