使用Spring CSRF和ajax Rest调用和带有Thymeleaf的HTML页面

luc*_*uca 8 html jquery spring csrf thymeleaf

我正在使用带有CSRF的Spring Security,我的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";
                    }
                });
            });
});
Run Code Online (Sandbox Code Playgroud)

一切正常,但当我打电话给这个函数时:

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);
    });
Run Code Online (Sandbox Code Playgroud)

我收到错误403.也许使用表单,使用thymeleaf,它工作正常但是第二种类型的请求我必须添加CSRF令牌.我试过了

var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
Run Code Online (Sandbox Code Playgroud)

在我的html页面中我添加了

!--  -->
<meta name="_csrf" th:content="${_csrf.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>
Run Code Online (Sandbox Code Playgroud)

为什么表格有效?我使用表单时不需要添加任何内容?使用浏览器的开发工具可以看到_csrf和_csrf_header的危险吗?谢谢

Ole*_*uts 8

这个解决方案为我工作尝试在Spring MVC和Thymeleaf中使用React / Ajax调用

<meta id="_csrf" name="_csrf" th:content="${_csrf.token}"/>
<meta id="_csrf_header" name="_csrf_header" th:content="${_csrf.headerName}"/>
Run Code Online (Sandbox Code Playgroud)

阿贾克斯:

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);
                        }
                    });
Run Code Online (Sandbox Code Playgroud)


Aes*_*eir 7

这很可能是因为没有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);
}
Run Code Online (Sandbox Code Playgroud)

总而言之,它将CSRF令牌附加到您通过ajax执行的任何发布请求.