[英]How to authenticate properly in post request with fetch api?
我有一个 SpringBoot 后端,在默认配置中启用了 Spring Security(那里没有任何变化)。
我有以下 Rest Controller 和 Post Mapping:
@RestController
public class MyController {
@PostMapping(value = "/sm/resrc/pth")
public Integer postSomething(@RequestParam String someValue,@RequestParam String userId){
System.out.println(String.format("SomeValue: %s from userid %s",someValue,userId));
return 0;
}
}
<form method="post" th:action="@{/sm/resrc/pth}">
<input type="text" name="someValue">
<input type="text" name="userId">
<input type="hidden" name="_csrf" value="${_csrf.token}" />
<div><input type="submit" value="Send" /></div>
</form>
它甚至可以在没有隐藏 cors 值的情况下工作。
let data = {
"some":"abc",
"values":this.localDescription,
"userId":userId
};
fetch("sm/resrc/pth",
{
method: 'POST',
credentials: 'include',
mode: 'cors',
body: data
}
).then(response => console.log(response));
我在用 jax-rs 做一个登录示例时发现了同样的问题。 在我的情况下,问题是当向请求添加 'credentials': 'include' 时,在 Rest Service API 一侧,需要在 CORS 过滤器中配置标头:
response.addHeader("Access-Control-Allow-Origin", "*");
到:
res.addHeader("Access-Control-Allow-Origin", "http://localhost");
其中“http://localhost 是我请求的来源。
我在这篇文章中找到了有关它的信息: 请求的资源上不存在“Access-Control-Allow-Origin”标头—当尝试从 REST API 获取数据时
CORS 是一项安全功能; 所以你可能不想禁用或绕过它。 我努力找出如何正确包含标题,但最终找到了解决方案。 我就是这样解决的:
在第一步中,我将预期的 CSRF-Header-name 和令牌本身添加到生成的 html 文件的元数据中。 在春季使用模板框架 thyemleaf 时,它看起来如下所示:
<html lang="en">
<head>
<meta name="_csrf_header_name" th:content="${_csrf.headerName}"/>
<meta name="_csrf_token" th:content="${_csrf.token}"/>
</head>
.
.
.
</html>
结果是这样的:
<meta name="_csrf_header_name" content="X-CSRF-TOKEN">
<meta name="_csrf_token" content="14d98c88-8643-1234-5678-39473aa7890e">
在获取请求中,CSRF Header 是从令牌和正确的 Header-name(从元标记中读取)构建的,正如服务器所预期的那样。
getCsrfToken(){
return document.querySelector('meta[name=_csrf_token]').content;
}
getCsrfTokenName(){
return document.querySelector('meta[name=_csrf_header_name]').content;
}
let csrfToken = this.getCsrfToken();
let csrfTokenName = this.getCsrfTokenName();
fetch('sm/resrc/pth', {
method:'post',
headers: new Headers([[csrfTokenName, csrfToken]])
}).then(res =>{console.log(res);});}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.