场景:
Spring Boot中使用Spring Security,前端登录使用Ajax提交表单,但总是报403,请求总被拒绝.
原因:
spring security默认开启了Cross Site Request Forgery (CSRF)。
当ajax post提交遇到403时,应当时缺少了csrf。
解决办法

在form表单中添加隐藏域csrf
<input type="hidden"
name="${_csrf.parameterName}"
value="${_csrf.token}"/>
<input type="button" onclick="login()" value="登陆">
完整表单如下:
<form th:action="@{/login}" method="post">
用户名:<input id="uname" name="uname"/><br>
密码:<input id="pwd" name="pwd"><br/>
记住我 <input type="checkbox" name="remember">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<input type="button" onclick="login()" value="登陆">
</form>
修改Ajax的url地址
$.ajax({
type:"POST",
url:"[[@{/login}]]?[(${_csrf.parameterName})]=[(${_csrf.token})]",
data:{
"uname":name,
"pwd":password
},
success:function (json) {
console.log(JSON.stringify(json));
},
error:function (e) {
alert(e.responseText);
}
});
head中添加
<meta name="_csrf" th:content="${_csrf.token}"/>
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>
js文件中添加
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);
});
完整代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>武林秘籍管理系统</title>
<meta name="_csrf" th:content="${_csrf.token}"/>
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>
</head>
<body>
<h1 align="center">欢迎登陆武林秘籍管理系统</h1>
<hr>
<div align="center">
<form th:action="@{/login}" method="post">
用户名:<input id="uname" name="uname"/><br>
密码:<input id="pwd" name="pwd"><br/>
记住我 <input type="checkbox" name="remember">
<input type="hidden"
name="${_csrf.parameterName}"
value="${_csrf.token}"/>
<input type="button" onclick="login()" value="登陆">
</form>
</div>
</body>
<script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
<script>
function login() {
var name = $("#uname").val();
var password = $("#pwd").val();
if (name===""||password===""){
alert("用户名和密码不能为空!");
}
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);
});
$.ajax({
type:"POST",
url:"[[@{/login}]]?[(${_csrf.parameterName})]=[(${_csrf.token})]",
data:{
"uname":name,
"pwd":password
},
success:function (json) {
var obj = JSON.stringify(json);
console.log(obj);
if (json['code'] === "login_ok"){
location.href="/";
}
},
error:function (e) {
alert(e.responseText);
}
});
}
</script>
</html>
留言