将 CSRFToken 添加到 Ajax 请求

Posted

技术标签:

【中文标题】将 CSRFToken 添加到 Ajax 请求【英文标题】:Adding CSRFToken to Ajax request 【发布时间】: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() 返回什么? 【参考方案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',可能是最糟糕的主意。我可以在控制台中直接打印它。您需要在客户端加密,然后在服务器端解密。

【讨论】:

你能把它翻译成英文吗? 您需要了解有关安全性的更多信息,因为您不知道自己在说什么

以上是关于将 CSRFToken 添加到 Ajax 请求的主要内容,如果未能解决你的问题,请参考以下文章

Django CSRFToken 中间件附加到 URL 并在向服务器发出“PUT”请求后显示。 (AJAX 问题)

JQueqy Ajax的使用(POST请求)

HTML中ajax表单提交CSRF保护

防止跨站攻击——CSRFToken

Django 设置 cookie 中的 csrftoken

Django设置cookie中的csrftoken