【问题标题】:Adding CSRFToken to Ajax request将 CSRFToken 添加到 Ajax 请求
【发布时间】:2020-05-23 15:01:13
【问题描述】:

我需要通过基于 Ajax 的发布请求传递 CSRFToken,但不确定如何以最佳方式完成此操作。 使用在请求中内部检查 CSRFToken 的平台(仅限 POST 请求)

最初我想把它添加到标题中

$(function() {
    $.ajaxSetup({
        headers : {
            'CSRFToken' : getCSRFTokenValue()
        }
    });
});

这将使它可用于每个 Ajax 请求,但它不适用于我的情况,因为请求中的 CSRFToken 仍然为空。

有什么方法可以为所有处理 POST 类型的 Ajax 调用设置 CSRFToken

编辑 如果我在我的 Ajax 调用中做这样的事情

data: {"newsletter-subscription-email" : "XXX" , 'CSRFToken': getCSRFTokenValue()},

一切正常。

我的问题是,我想将 CSRFToken 值作为请求参数而不是作为请求标头传递

【问题讨论】:

  • 所以header传了但是token为null? getCSRFTokenValue() 到底是做什么的?
  • @RobinJonsson:这只是获取代币的价值
  • 我面临同样的问题(需要在基于 Ajax 的帖子上传递 CSRF 令牌,但仅使用 JS。我不熟悉 JQuery :(
  • 你从 getCSRFTokenValue() 返回什么?

标签: javascript jquery ajax


【解决方案1】:

这个怎么样,

$("body").bind("ajaxSend", function(elm, xhr, s){
   if (s.type == "POST") {
      xhr.setRequestHeader('X-CSRF-Token', getCSRFTokenValue());
   }
});

参考:http://erlend.oftedal.no/blog/?blogid=118

CSRF作为参数传递,

        $.ajax({
            type: "POST",
            url: "file",
            data: { CSRF: getCSRFTokenValue()}
        })
        .done(function( msg ) {
            alert( "Data: " + msg );
        });

【讨论】:

  • 谢谢,虽然值被传递了,但它在请求中不可用,这是从服务器端的请求中获取它的方式request.getParameter(CSRF_PARAM_NAME)
  • request.getParameter(CSRF) 在您的服务器端。请检查我的更新答案
  • 谢谢!!,我知道这种方式,但在这种情况下,这意味着我需要将它添加到我将在我的应用程序中执行的每个 Ajax 调用中
  • 是的!您可以使用获取标头响应 csrf 令牌
  • 这会在 s.type 上出现错误
【解决方案2】:

你可以用这个:

var token = "SOME_TOKEN";

$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
  jqXHR.setRequestHeader('X-CSRF-Token', token);
});

来自文档:

jQuery.ajaxPrefilter( [dataTypes ], handler(options, originalOptions, jqXHR) )

描述:处理自定义 Ajax 选项或修改现有选项 在发送每个请求之前以及在它们被 $.ajax() 处理之前。

Read

【讨论】:

  • 谢谢,虽然值被传递了,但它在请求中不可用,这是从服务器端的请求中获取它的方式request.getParameter(CSRF_PARAM_NAME)
  • @UmeshAwasthi 你使用 node.js 吗?
  • 不,我正在为此使用 Jquery
  • 谢谢!我曾经使用$ .ajaxSetup 配置,并且由于无法识别的 X-CSRF-TOKEN 标头而拒绝请求的其他服务器存在 API 问题。现在它将完美运行。
【解决方案3】:

这是我在使用 ajax 发送 POST 请求时用来防止 CSRF 令牌问题的代码

$(document).ready(function(){
    function getCookie(c_name) {
        if(document.cookie.length > 0) {
            c_start = document.cookie.indexOf(c_name + "=");
            if(c_start != -1) {
                c_start = c_start + c_name.length + 1;
                c_end = document.cookie.indexOf(";", c_start);
                if(c_end == -1) c_end = document.cookie.length;
                return unescape(document.cookie.substring(c_start,c_end));
            }
        }
        return "";
    }

    $(function () {
        $.ajaxSetup({
            headers: {
                "X-CSRFToken": getCookie("csrftoken")
            }
        });
    });

});

【讨论】:

  • 我使用了你的 getCookie 函数。它是有益的。谢谢
【解决方案4】:

来自 JSP

<form method="post" id="myForm" action="someURL">
    <input name="csrfToken" value="5965f0d244b7d32b334eff840...etc" type="hidden">    
</form>

这是在挣扎了 3 小时后对我有用的最简单的方法,只需像这样从输入隐藏字段中获取令牌,并且在执行 AJAX 请求时只需在标头中传递此令牌,如下所示:-

来自 Jquery

var token =  $('input[name="csrfToken"]').attr('value'); 

来自纯 Javascript

var token = document.getElementsByName("csrfToken").value;

最终的 AJAX 请求

$.ajax({
      url: route.url,
      data : JSON.stringify(data),
      method : 'POST',
      headers: {
                    'X-CSRF-Token': token 
               },
      success: function (data) { ...      },
      error: function (data) { ...  }

});

现在您不需要在 web config 中禁用 crsf 安全性,这也不会在控制台上出现 405(Method Not Allowed) 错误。

希望这会对人们有所帮助..!!

【讨论】:

    【解决方案5】:

    如果您正在使用 lusca 在 node.js 中工作,请尝试以下操作:

    $.ajax({
    url: "http://test.com",
    type:"post"
    headers: {'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')}
    })
    

    【讨论】:

      【解决方案6】:

      这对我有用(使用 jQuery 2.1)

      $(document).ajaxSend(function(elm, xhr, s){
          if (s.type == "POST") {
              s.data += s.data?"&":"";
              s.data += "_token=" + $('#csrf-token').val();
          }
      });
      

      或者这个:

      $(document).ajaxSend(function(elm, xhr, s){
          if (s.type == "POST") {
              xhr.setRequestHeader('x-csrf-token', $('#csrf-token').val());
          }
      });
      

      (其中#csrf-token 是包含令牌的元素)

      【讨论】:

        【解决方案7】:

        我在博客的帖子列表中遇到了这个问题,帖子在foreach内的视图中,然后在javascript中很难选择它,并且帖子方法和令牌的问题也存在。

        这是视图末尾的 javascript 代码,我在视图内部的 javascript 函数中生成令牌,而不是在外部 js 文件中,然后很容易使用 php lavarel 使用 csrf_token() 函数生成它,然后发送直接在参数中的“删除”方法。 你可以看到我没有在 var route: {{ route('post.destroy', $post->id}} 中使用,因为我不知道我想要删除的 id 直到有人点击销毁按钮,如果你没有这个问题你可以使用 {{ route('post.destroy', $post->id}} 或其他类似的。

          $(function(){
            $(".destroy").on("click", function(){
                 var vid = $(this).attr("id");
                 var v_token = "{{csrf_token()}}";
                 var params = {_method: 'DELETE', _token: v_token};
                 var route = "http://imagica.app/posts/" + vid + "";
            $.ajax({
                 type: "POST",
                 url: route,
                 data: params
            });
           });
          });
        

        这是视图中的内容代码(在foreach内部有更多的表单和每个帖子的数据,但在这个例子中并不重要),你可以看到我在按钮上添加了一个“删除”类,我在里面调用了类javascript。

              @foreach($posts as $post)
                  <form method="POST">
                    <button id="{{$post->id}}" class="btn btn-danger btn-sm pull-right destroy" type="button" >eliminar</button>
                  </form>
              @endforeach
        

        【讨论】:

          【解决方案8】:

          上面的答案对我不起作用。

          我在我的 ajax 请求之前添加了以下代码:

          function getCookie(name) {
                          var cookieValue = null;
                          if (document.cookie && document.cookie != '') {
                              var cookies = document.cookie.split(';');
                              for (var i = 0; i < cookies.length; i++) {
                                  var cookie = jQuery.trim(cookies[i]);
                                  // Does this cookie string begin with the name we want?
                                  if (cookie.substring(0, name.length + 1) == (name + '=')) {
                                      cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                                      break;
                                  }
                              }
                          }
                          return cookieValue;
                      }
                      var csrftoken = getCookie('csrftoken');
          
                      function csrfSafeMethod(method) {
                          // these HTTP methods do not require CSRF protection
                          return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
                      }
          
                      $.ajaxSetup({
                          beforeSend: function(xhr, settings) {
                              if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                                  xhr.setRequestHeader("X-CSRFToken", csrftoken);
                              }
                          }
                      });
          
                      $.ajax({
                               type: 'POST',
                               url: '/url/',
                      });
          

          【讨论】:

            【解决方案9】:

            每个人都使用:var myVar = 'token',可能是最糟糕的主意。我可以在控制台中直接打印它。您需要在客户端加密,然后在服务器端解密。

            【讨论】:

            • 你能把它翻译成英文吗?
            • 您需要了解有关安全性的更多信息,因为您不知道自己在说什么
            猜你喜欢
            • 2013-12-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-09-19
            • 2013-01-09
            • 2016-09-28
            相关资源
            最近更新 更多