【问题标题】:Rails does not generate an authenticity tokenRails 不会生成真实性令牌
【发布时间】:2015-12-08 22:05:29
【问题描述】:

我完全按照这两个教程,

并在 Rails 中实现一个简单的评论系统。但是,我在处理提交时遇到了问题。我实现了一个简单的 AJAX POST 请求来发送我的表单数据(作为状态)。它看起来像这样:

var CommentForm = React.createClass({
    handleChange: function(e) {
    var name, obj;
    name = e.target.name;
    return this.setState((
      obj = {},
      obj["" + name] = e.target.value,
      obj
    ));
  },
    handleSubmit: function(e) {
        e.preventDefault();
        var author = React.findDOMNode(this.refs.author).value.trim();
        var text   = React.findDOMNode(this.refs.text).value.trim();
        if(!text || !author) {
            return;
        }
        $.post(this.props.postUrl, {comment: this.state}, null, "application/json");
        React.findDOMNode(this.refs.author).value = '';
        React.findDOMNode(this.refs.text).value = '';
    },
    render: function() {
        return (
            <form className="commentForm" onSubmit={this.handleSubmit}>
        <input type="text" placeholder="Your name" ref="author" name="author" onChange={this.handleChange} />
        <input type="text" placeholder="Say something..." ref="text" name="text" onChange={this.handleChange} />
        <input type="submit" value="Post" />
      </form>
        );
    }
});

当我检查控制台时,看起来它正在传递到正确的路线和正确的参数,除了没有authentity_token 参数。这是控制台中的屏幕截图。

在我提供的第一个链接中,据说 jquery_ujs 处理生成真实性令牌并将其传递给 Ajax POST。但是,在我的情况下,情况并非如此。我错过了什么?

编辑: 我有几个答案可以解决我的问题。但是,我仍然很好奇我的代码与本教程中的代码之间的区别是什么?

【问题讨论】:

    标签: ruby-on-rails ajax reactjs csrf


    【解决方案1】:

    这是因为您在 render 方法中缺少传递 authenticity_token 的方法。要么禁用真实性检查(不建议推荐),要么使用真实性令牌交付呈现的表单。

    在这种情况下,我建议使用 Gon 将控制器变量干净地传递给 JS:https://github.com/gazay/gon

    安装时:

    在你的控制器方法中:

    gon.authenticity_token = form_authenticity_token
    

    在你的反应类中:

    <form className="commentForm" onSubmit={this.handleSubmit}>
        <input type="hidden" name="authenticity_token" value={gon.authenticity_token}  />
        <input type="text" placeholder="Your name" ref="author" name="author" onChange={this.handleChange} />
        <input type="text" placeholder="Say something..." ref="text" name="text" onChange={this.handleChange} />
        <input type="submit" value="Post" />
    </form>
    

    【讨论】:

    • 感谢您的解决方案!我也没有考虑禁用检查。但我仍然想知道他的教程和我的代码有什么不同?
    • 我刚刚查看了他的教程,他没有粘贴他的ApplicationController,所以我无法判断他是否激活了protect_from_forgery,至少在他自己的控制器中他没有使用它
    • 是的,我也想过,但他明确表示:“如果您使用其他 JS 框架和 Rails(例如,AngularJS)来构建类似的功能,您可能会遇到问题,因为您的 POST 请求不包含 Rails 所需的 CSRF 令牌,那么,为什么我们没有遇到同样的问题?很简单,因为我们使用 jQuery 与后端交互,并且 Rails 的 jquery_ujs 不显眼的驱动程序将包含 CSRF对我们的每个 AJAX 请求都有令牌。酷!”这就是让我感到困惑的地方。刚刚给他发了一封电子邮件。
    • 我明白了,我没有提到那个部分,但我想知道它是否与 github.com/rails/jquery-ujs/blob/master/src/rails.js#L70 有关 - 你能确认你的 ajax 调用正在发送请求标头 X-CSRF-Token 吗?
    • 因为您可能忘记在布局中包含 apidock.com/rails/ActionView/Helpers/CsrfHelper/csrf_meta_tags,这将解释要包含在请求标头中的缺失值。
    【解决方案2】:

    您可以将authenticity_token 属性添加到您的AJAX POST

    你可以替换这一行:

    $.post(this.props.postUrl, {comment: this.state}, null, "application/json");
    

    用这个:

    $.post(this.props.postUrl, {
        comment: this.state,
        authenticity_token: $('meta[name=csrf-token]').attr('content')
      }, null, "application/json");
    

    【讨论】:

      【解决方案3】:

      已解决。 删除线

      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      

      来自 application.html.erb。事实证明,它在发出 AJAX 请求时隐藏了 jquery_rails。

      【讨论】:

        猜你喜欢
        • 2011-03-04
        • 2013-04-21
        • 1970-01-01
        • 2011-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-29
        • 2013-07-22
        相关资源
        最近更新 更多