简体   繁体   English

如何将csrf标记添加到ajax请求

[英]How to add csrf token to ajax request

I have issues adding csrf to ajax request. 我有问题将csrf添加到ajax请求。 I'm using thymeleaf on client side with spring-boot/spring security. 我在客户端使用百里香叶弹簧/弹簧安全。 Spring security wouldn't allow the request because csrf-token is missing. Spring安全性不允许该请求,因为缺少csrf-token。 Here is my code for ajax 这是我的ajax代码

function bits(){
    var xhttp = new XMLHttpRequest();
    var selected = document.getElementById("product").value;
    xhttp.onreadystatechange = function(){
      if(xhttp.readyState==4 && xhttp.status==200){
        var result= JSON.parse(xhttp.responseText)
        var length = result.length;
        for(i=0; i<length; i++){

           console.log(result[k].spid);
        }
    }

};

 xhttp.open("POST", "http://localhost:8080/bids?q="+selected,  true);
 xhttp.send();

} }

Help will be appreciated 帮助将不胜感激

I modified @Prakash Hari Sharma's solution and had the following code that worked for me. 我修改了@Prakash Hari Sharma的解决方案,并有以下代码对我有用。 Note, th: prefix if using Thymeleaf. 注意,th:前缀如果使用Thymeleaf。

--Header section - 头部分

<meta th:name="_csrf" th:content="${_csrf.token}"/>
<meta th:name="_csrf_header" th:content="${_csrf.headerName}"/>

Ajax script function Ajax脚本功能

...
...
var token = $("meta[name='_csrf']").attr("content"); 
var header = $("meta[name='_csrf_header']").attr("content");
...
...
xhttp.open("POST", "http://localhost:8080/bids?q="+selected,  true);
xhttp.setRequestHeader(header, token);
xhttp.send();

Hope this helps someone too. 希望这也有助于某人。

As a complementary to @EdwardoS answer, after you add meta tags to the <head> element: 作为@EdwardoS答案的补充,在向<head>元素添加元标记后:

Thymeleaf: Thymeleaf:

<meta th:name="_csrf" th:content="${_csrf.token}"/>
<meta th:name="_csrf_header" th:content="${_csrf.headerName}"/>

JSP: JSP:

<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>

...you can then do what is suggested in Spring documentation and have all your future ajax to include csrf : ...然后,您可以执行Spring文档中的建议,并将所有未来的ajax包含在csrf

$(function () {
    var token = $("meta[name='_csrf']").attr("content");
    var header = $("meta[name='_csrf_header']").attr("content");
    $(document).ajaxSend(function (e, xhr, options) {
        xhr.setRequestHeader(header, token);
    });
});

Store CSRF Token in your jsp meta tags 将CSRF令牌存储在您的jsp元标记中

<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>

and add values of csrf token in ajax request 并在ajax请求中添加csrf标记的值

var elementToken = document.querySelector('meta[property="_csrf"]');
var token = elementToken && elementToken.getAttribute("content");
var elementHeader = document.querySelector('meta[property="_csrf_header"]');
var header = elementHeader && elementHeader.getAttribute("content");
xhttp.open("POST", "http://localhost:8080/bids?q="+selected,  true);
xmlhttp.setRequestHeader(header, token);
xhttp.send();

In spring documentation, it is also suggested that you do not use csrf token in GET requests for security reasons 在spring文档中,还建议您出于安全原因不在GET请求中使用csrf标记

"The ability to scope which requests receive the token helps guard against leaking the CSRF token to a third party." “能够确定接收令牌的请求的范围有助于防止将CSRF令牌泄露给第三方。”

You can therefore filter to pass token only for POST requests with following manner: 因此,您可以通过以下方式过滤仅为POST请求传递令牌:

$(function() {
    var token = $("meta[name='_csrf']").attr("content");
    var header = $("meta[name='_csrf_header']").attr("content");
    $(document).ajaxSend(function(e, xhr, options) {
        if (options.type == "POST") {
            xhr.setRequestHeader(header, token);
        }
    });
});

The meta tags in <head> element would be the same as in previous answers: <head>元素中的元标记与之前的答案中的元标记相同:

<meta th:name="_csrf" th:content="${_csrf.token}"/>
<meta th:name="_csrf_header" th:content="${_csrf.headerName}"/>

below you can find my code to use ajax with csrf. 下面你可以找到我的代码来使用ajax和csrf。 I use Spring Security too. 我也使用Spring Security。

    // In your JSP meta tags
    <meta name="_csrf" content="${_csrf.token}"/>
    <!-- default header name is X-CSRF-TOKEN -->
    <meta name="_csrf_header" content="${_csrf.headerName}"/>

    // In your javascript
    // CSRF Variables
    var _tc = $("meta[name='_csrf']").attr("content");
    var _hc = $("meta[name='_csrf_header']").attr("content");


    // Header
    var headersStomp = {};
    headersStomp[_hc] = _tc;

    $(document).ajaxSend(function(e, xhr, options) {
        xhr.setRequestHeader(_hc, _tc);
    });

You can set the Spring Security's CSRF Token into a Javascript variable called MyApp.csrfToken . 您可以将Spring Security的CSRF令牌设置为名为MyApp.csrfToken的Javascript变量。

In your JSP , add the flowing script to call the init function once your document is ready: JSP中 ,添加流动的脚本以在文档准备好后调用init函数:

<script type="text/javascript">
    document.onreadystatechange = function () {
       var state = document.readyState;
       if (state == 'complete') {
         fnInit("${_csrf.parameterName}", "${_csrf.token}"); 
       }
    }​;
</script>

In your JS file, define the fnInit function JS文件中,定义fnInit函数

var MyApp = MyApp || {};
function fnInit(csrfParam, csrfToken) {
  MyApp.csrfToken = {
      param : csrfParam,
      value : csrfToken
  }
}

Now you have the token ready to use in any ajax call 现在您已准备好在任何ajax调用中使用令牌

...
...
xhttp.open("POST", "http://localhost:8080/bids?q="+selected + "&"+ MyApp.csrfToken.param+"="+ MyApp.csrfToken.value,  true);
xhttp.send();

PS: No need for jQuery, it is pure JavaScript. PS: 不需要 jQuery,它是纯JavaScript。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM