I have a SpringBoot Backend with Spring Security Enabled in the default configuration (nothing changed there).
I have following Rest Controller and 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>
It does even work without the hidden cors value.
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));
I've found the same problem doing a login example with jax-rs. In my case the problem was that when add the 'credentials': 'include' to the request, on the side of the Rest Service API, need configure in the CORS Filter the header from:
response.addHeader("Access-Control-Allow-Origin", "*");
to:
res.addHeader("Access-Control-Allow-Origin", "http://localhost");
Where "http://localhost is the origin of my request.
I've found information about it in this post: No 'Access-Control-Allow-Origin' header is present on the requested resource—when trying to get data from a REST API
CORS is a security feature; So you probably don't want to disable or bypass it. I struggled a bit to find out, how to include the headers correctly but finally found the solution. That's how I solved it:
In the first step I added the expected CSRF-Header-name and the token itself to the metadata of the generated html file. In spring using the templating framework thyemleaf it looks like following:
<html lang="en">
<head>
<meta name="_csrf_header_name" th:content="${_csrf.headerName}"/>
<meta name="_csrf_token" th:content="${_csrf.token}"/>
</head>
.
.
.
</html>
Which results in something like that:
<meta name="_csrf_header_name" content="X-CSRF-TOKEN">
<meta name="_csrf_token" content="14d98c88-8643-1234-5678-39473aa7890e">
In the fetch request, the CSRF Header is built from the token and the correct Header-name (which are read from the meta tags) just as expected from the server.
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);});}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.