我在向ajax请求添加csrf时遇到问题。我在客户端使用百日咳采用弹簧/弹簧安全装置。 Spring安全性不允许该请求,因为缺少csrf-token。这是我的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();
}
帮助将不胜感激
答案 0 :(得分:10)
我修改了@Prakash Hari Sharma的解决方案并使用了以下代码。注意,如果使用Thymeleaf,则为:前缀。
- 标题部分
<meta th:name="_csrf" th:content="${_csrf.token}"/>
<meta th:name="_csrf_header" th:content="${_csrf.headerName}"/>
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();
希望这也有助于某人。
答案 1 :(得分:4)
作为@EdwardoS答案的补充,将元标记添加到$scope.lists = {
"count": 6,
"brands": [{
"number": 9,
"brand": "aaaaa"
}, {
"number": 3,
"brand": "project management"
}, {
"number": 2,
"brand": "adasdadasd"
}, {
"number": 2,
"brand": "gsdfgrtwetwert"
}, {
"number": 2,
"brand": "dfghgdfghdfgh"
}, {
"number": 2,
"brand": "dfghdfghrtr"
}]
};
元素后:
Thymeleaf:
<head>
JSP:
<meta th:name="_csrf" th:content="${_csrf.token}"/>
<meta th:name="_csrf_header" th:content="${_csrf.headerName}"/>
...然后,您可以执行Spring documentation中建议的操作,并将所有未来的ajax包含在<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>
中:
csrf
答案 2 :(得分:3)
将CSRF令牌存储在您的jsp元标记中
<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>
并在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();
答案 3 :(得分:3)
在spring文档中,还建议您出于安全原因不在GET请求中使用csrf令牌
“能够确定接收令牌的请求的范围有助于防范 反对将CSRF令牌泄露给第三方。“
因此,您可以通过以下方式过滤仅为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);
}
});
});
<head>
元素中的元标记与之前的答案相同:
<meta th:name="_csrf" th:content="${_csrf.token}"/>
<meta th:name="_csrf_header" th:content="${_csrf.headerName}"/>
答案 4 :(得分:2)
// 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);
});
答案 5 :(得分:0)
您可以将Spring Security的CSRF令牌设置为名为MyApp.csrfToken
的Javascript变量。
在 JSP 中,添加流动的脚本,在文档准备就绪后调用init函数:
<script type="text/javascript">
document.onreadystatechange = function () {
var state = document.readyState;
if (state == 'complete') {
fnInit("${_csrf.parameterName}", "${_csrf.token}");
}
};
</script>
在 JS 文件中,定义fnInit
函数
var MyApp = MyApp || {};
function fnInit(csrfParam, csrfToken) {
MyApp.csrfToken = {
param : csrfParam,
value : csrfToken
}
}
现在,您可以在任何ajax调用中使用准备好使用
...
...
xhttp.open("POST", "http://localhost:8080/bids?q="+selected + "&"+ MyApp.csrfToken.param+"="+ MyApp.csrfToken.value, true);
xhttp.send();
PS:对于jQuery不需要,它是纯JavaScript。