【问题标题】:react with Rails 5, getting CSRF error for post with axios对 Rails 5 做出反应,使用 axios 发布 CSRF 错误
【发布时间】:2017-12-11 20:21:44
【问题描述】:

我正在尝试使用 react_on_rails 来构建我的第一个带有 react 和 rails 的示例。我正在尝试将一些数据保存到rails后端,使用axios作为ajax。

这是我的代码:

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);
    });
}

和组件:

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>
    );
  }
}

问题是当我点击提交时,我的后端报告了

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):

首先,我不明白为什么参数似乎被传递了两次,但这甚至没有产生警告,所以现在不要在意。

问题是我看不到在我的反应代码中获取 CSRF 令牌以在post 请求中使用的方法

我应该禁用 CSRF 吗?或者,还有更好的方法?

【问题讨论】:

    标签: ruby-on-rails ajax reactjs csrf axios


    【解决方案1】:

    ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):

    Rails 通过将authenticity_token 附加到每个非 GET 请求(POST、PUT/PATCH 和 DELETE)来处理 CSRF 攻击。该错误意味着您没有在请求参数中发送authencity_token,您应该将一个唯一 authenticity_token 附加到params,类似于"authuenticity_token" =&gt; "BsfdgtZ1hshxgthjj" 应该解决问题。

    【讨论】:

      【解决方案2】:

      react_on_rails 通过提供两个助手来处理这个问题。来自react_on_railsdocumentation

      Rails 具有针对跨站点请求伪造 (CSRF) 的内置保护,请参阅 Rails 文档。为了在 JavaScript 请求中很好地利用此功能,React on Rails 提供了两个帮助器,可用于以下 POST、PUT 或 DELETE 请求:

      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);
      

      【讨论】:

        【解决方案3】:

        我发现react_on_rails有一个辅助系统来处理CSRF令牌,

        它基本上使用:

          <%= csrf_meta_tags %>
        

        将 csrf_token 作为元数据添加到页面的标题中

        然后你可以使用:

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

        获取并使用它。

        【讨论】:

        • 我唯一的疑问是将authenticity_token 硬连线,而在标题中我看到csrf-param 设置令牌的名称。
        猜你喜欢
        • 2017-07-28
        • 1970-01-01
        • 2022-07-26
        • 1970-01-01
        • 2021-11-15
        • 2016-11-02
        • 2022-06-16
        • 1970-01-01
        • 2018-10-27
        相关资源
        最近更新 更多