Spring CSRF 与 ajax 休息呼叫和 HTML 页面与 Thymeleaf 一起使用
Use of Spring CSRF with ajax Rest call and HTML page with Thymeleaf
我正在使用 Spring CSRF 安全性,但我的 javascript 中的一些 POST 调用有问题。对于我的页面,我使用 Thymeleaf 和 HTML 5,对于对我的控制器的 Rest 调用,我使用 jQuery.ajax。
如果我像这样使用 ajax 调用我的表单:
$(function() {
$("#saveCarButton").click(
function() {
var form = $("#addCarForm");
$.ajax({
type : "POST",
url : form.attr("action"),
data : form.serialize(),
// all right with rest call
success : function(data) {...}
//error during rest call
error : function(data) {
window.location.href = "/500";
}
});
});
});
一切正常,但是当我调用这个函数时:
jQuery.ajax({
url : 'upload',
type: 'POST',
contentType: false,
processData: false,
data:formData,
beforeSend:function(xhr) {
waitingModal.showPleaseWait();
},
success: function(data,status,xhr){...}
error: function(xhr,status,e){
}
}).complete(function() {
//add timeout because otherwise user could see a too fast waiting modal
setTimeout(function(){
waitingModal.hidePleaseWait();
}, 1000);
});
我收到错误 403。
也许在表单中,使用 thymeleaf,它工作正常,但对于第二种类型的请求,我必须添加 CSRF 令牌。
我试过
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
并在我的 html 页面中添加了
!-- -->
<meta name="_csrf" th:content="${_csrf.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>
为什么它与表单一起工作?
使用表格时我不必添加任何内容吗?
使用浏览器的开发工具可以看到 _csrf 和 _csrf_header 是否有危险?
谢谢
这很可能是因为没有通过 CSRF 令牌发送 403。
这是解决这类问题的方法(至少对我而言)。
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);
}
总之,它将 CSRF 令牌附加到您通过 ajax 执行的任何 post 请求。
这个解决方案对我有用
<meta id="_csrf" name="_csrf" th:content="${_csrf.token}"/>
<meta id="_csrf_header" name="_csrf_header" th:content="${_csrf.headerName}"/>
Ajax:
var token = $('#_csrf').attr('content');
var header = $('#_csrf_header').attr('content');
$.ajax({
type: "POST",
url: url,
beforeSend: function(xhr) {
xhr.setRequestHeader(header, token);
},
success: function(data, textStatus, jqXHR) {
alert(status);
},
error: function(request, status, error) {
alert(status);
}
});
我正在使用 Spring CSRF 安全性,但我的 javascript 中的一些 POST 调用有问题。对于我的页面,我使用 Thymeleaf 和 HTML 5,对于对我的控制器的 Rest 调用,我使用 jQuery.ajax。 如果我像这样使用 ajax 调用我的表单:
$(function() {
$("#saveCarButton").click(
function() {
var form = $("#addCarForm");
$.ajax({
type : "POST",
url : form.attr("action"),
data : form.serialize(),
// all right with rest call
success : function(data) {...}
//error during rest call
error : function(data) {
window.location.href = "/500";
}
});
});
});
一切正常,但是当我调用这个函数时:
jQuery.ajax({
url : 'upload',
type: 'POST',
contentType: false,
processData: false,
data:formData,
beforeSend:function(xhr) {
waitingModal.showPleaseWait();
},
success: function(data,status,xhr){...}
error: function(xhr,status,e){
}
}).complete(function() {
//add timeout because otherwise user could see a too fast waiting modal
setTimeout(function(){
waitingModal.hidePleaseWait();
}, 1000);
});
我收到错误 403。 也许在表单中,使用 thymeleaf,它工作正常,但对于第二种类型的请求,我必须添加 CSRF 令牌。 我试过
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
并在我的 html 页面中添加了
!-- -->
<meta name="_csrf" th:content="${_csrf.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>
为什么它与表单一起工作? 使用表格时我不必添加任何内容吗? 使用浏览器的开发工具可以看到 _csrf 和 _csrf_header 是否有危险? 谢谢
这很可能是因为没有通过 CSRF 令牌发送 403。
这是解决这类问题的方法(至少对我而言)。
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);
}
总之,它将 CSRF 令牌附加到您通过 ajax 执行的任何 post 请求。
这个解决方案对我有用
<meta id="_csrf" name="_csrf" th:content="${_csrf.token}"/>
<meta id="_csrf_header" name="_csrf_header" th:content="${_csrf.headerName}"/>
Ajax:
var token = $('#_csrf').attr('content');
var header = $('#_csrf_header').attr('content');
$.ajax({
type: "POST",
url: url,
beforeSend: function(xhr) {
xhr.setRequestHeader(header, token);
},
success: function(data, textStatus, jqXHR) {
alert(status);
},
error: function(request, status, error) {
alert(status);
}
});