[英]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.