Rails - 如何向用 javascript 创建的表单添加 CSRF 保护?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8503447/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 06:17:08  来源:igfitidea点击:

Rails - How to add CSRF Protection to forms created in javascript?

javascriptruby-on-railsruby-on-rails-3backbone.jscsrf

提问by CamelCamelCamel

I'm using backbone.js and it works great. but the forms I'm creating as a javascript template lacks the rails csrf protection token. How do I add it to templates I'm creating in javascript?

我正在使用backbone.js,效果很好。但是我作为 javascript 模板创建的表单缺少 rails csrf 保护令牌。如何将其添加到我在 javascript 中创建的模板中?

采纳答案by Thong Kuah

If you have <%= csrf_meta_tag %>in your layout somewhere and that is accessible to you from the js, then you can access it using $('meta[name="csrf-token"]')

如果您<%= csrf_meta_tag %>的布局中有某个地方并且您可以从 js 访问它,那么您可以使用$('meta[name="csrf-token"]')

See http://eunikorn.blogspot.com/2011/07/working-with-backbonejs-in-harmony-with.htmlfor an idea on how to hack in csrf support into each backbone request

请参阅http://eunikorn.blogspot.com/2011/07/working-with-backbonejs-in-harmony-with.html了解如何将 csrf 支持嵌入到每个主干请求中

回答by lucianosousa

Best way I solved this, inside the form:

我解决这个问题的最好方法,在表格中:

<%= hidden_field_tag :authenticity_token, form_authenticity_token %>

回答by suga_shane

You can prepend the csrf token to every form that uses 'post' or 'delete'. Here it is in coffeescript:

您可以在每个使用“post”或“delete”的表单前添加 csrf 标记。这是在咖啡脚本中:

$ -> 
  for f in $("form")
    if f.method == 'post' or f.method == 'delete'
      $(f).prepend("<input type='hidden' name='authenticity_token' value='" + token + "'>")

Make sure you have <%= csrf_meta_tags %> in your layout. It should already be in the standard 'application' layout, but add it if you're using a different layout.

确保您的布局中有 <%= csrf_meta_tags %> 。它应该已经在标准的“应用程序”布局中,但如果您使用不同的布局,请添加它。

回答by juliangonzalez

As for Rails 4.2.2 you are not allowed to use

至于 Rails 4.2.2 你不允许使用

<%= hidden_field_tag :authenticity_token, form_authenticity_token %>

from your .js.erbassets file.

从您的.js.erb资产文件。

However You can create the form inside the .js.erbfile and in the view containing the form .html.erbfile use the hidden_field_taghelper to generate the token element. As this element is going to be generated outside the form you can use jquery to append this element to the form.

但是,您可以在.js.erb文件内创建表单,并在包含表单.html.erb文件的视图中使用hidden_field_tag帮助程序生成令牌元素。由于此元素将在表单之外生成,因此您可以使用 jquery 将此元素附加到表单中。

Case of study: SweetAlert (first version, version too seems to have solved this problem)

学习案例:SweetAlert(第一个版本,这个版本好像也解决了这个问题)

show.js.erb

显示.js.erb

$('.js-button-apply-offer').click(function(e) {
var urlOffer = $(this).attr('data-url-offer');
var modalParams = {
    type: 'warning',
    title: 'add file',
    text: '<p>Need to add a file before continuing</p>' // This is a hack for Sweet alert, solved in SweetAlert2 Consider upgrade
    +"<form action='"+urlOffer+"' id='formCustomCV' method='post' enctype='multipart/form-data' data-remote='true'>"
    + "<input type='file' name='custom_cv' id='fileToUploadAlert' accept='application/pdf'>\n"
    +"</form>",
    html: true,
    showCancelButton: true,
    confirmButtonColor: '#DD6B55',
    confirmButtonText: 'Send',
    cancelButtonText: 'Cancel',
    closeOnConfirm: false
  }
swal(modalParams,
function(){
  var form_token = $('#form_token');
  $('#formCustomCV').append(form_token).submit(); //update to submit using ajax
});

show.html.erb

显示.html.erb

<%= button_tag t('offers.offer.apply'),
  class: 'center-block btn btn-success js-button-apply-offer',
  id: "js-button-apply-offer",
  data: {
    url_offer: apply_talents_offer_path(@offer),
  } 
%>
<%= hidden_field_tag :authenticity_token, form_authenticity_token, id: :form_token %>

回答by James Hibbard

I have a form inside a Vue component in a Rails 6 app.

我在 Rails 6 应用程序中的 Vue 组件中有一个表单。

To my surprise, it was sufficient to include a hidden input with the name authenticity_tokenwithin the Vue template and on page load, Rails filled out the value with a CSRF protection token.

令我惊讶的是,authenticity_token在 Vue 模板中包含一个带有名称的隐藏输入就足够了,并且在页面加载时,Rails 用 CSRF 保护令牌填充了该值。

E.g.

例如

<template>
  <div id="app">
    <form
      action="/submit"
      method="post"
      @submit.prevent="onSubmit"
    >
      <input
        type="hidden"
        name="authenticity_token"
        value=""
      >
      <!-- rest of form -->
    </form>
  </div>
</template>

Which gets rendered as:

呈现为:

<div id="app">
  <form action="/submit" method="post">
    <input type="hidden" name="authenticity_token" value="zl9PJiE...">
    ...
  </form>
</div>