我知道这个问题已经被问过很多次了,但是我试过了大多数的答案,仍然不能让它起作用。
我有一个带有net/http包的Golang API和一个JS前端。我有一个函数
func SetCookie(w *http.ResponseWriter, email string) string {
val := uuid.NewString()
http.SetCookie(*w, &http.Cookie{
Name: "goCookie",
Value: val,
Path: "/",
})
return val
}
这个函数在用户登录时被调用,我希望它被发送到所有其他端点,这在Postman中也能正常工作,但是,当涉及到浏览器时,我似乎无法让它记住cookie,甚至无法将其发送到其他端点。
使用端点的JS示例
async function getDataWithQuery(query, schema){
let raw = `{"query":"${query}", "schema":"${schema}"}`;
let requestOptions = {
method: 'POST',
body: raw,
redirect: 'follow',
};
try{
let dataJson = await fetch("http://localhost:8080/query/", requestOptions)
data = await dataJson.json();
}catch(error){
console.log(error);
}
return data;
}
我尝试过在Golang中设置SameSite
属性,或者在JS中使用credential: "include"
,但没有成功。
1条答案
按热度按时间sg3maiej1#
多亏了评论中的讨论,我发现了一些关于这个问题的提示。
保存cookie(API和前端在同一主机上)
我使用
document.cookie
来保存cookie。我手动设置选项,因为在APIfetch
的响应上调用res.cookie
只返回值。document.cookie =
goCookie=${res.cookie}; path=/; domain=localhost;`就是一个例子。发送cookie
这在之前的问题中已经回答过了,在评论中又回答了一次,问题是我用了
credential:'include'
而不是正确的credentials:'include'
(复数)。CORS和Cookie
如果API和前端不在同一主机上,则必须同时修改API和前端。
前端
Cookie必须具有API的域,因为是API而不是前端需要它。因此,出于安全原因,你不能为域设置cookie(API)从另一个域一个解决方案是将用户重定向到一个API端点,该端点在响应头中返回
Set-Cookie
头。此解决方案向浏览器发出信号,以向附加到该cookie的域注册该cookie(API的域,因为是API发送的)。此外,您仍然需要在前端中包含
credentials:'include'
。API
你需要设置一些头文件,我设置的是
你需要公开前端将重定向用户的端点,并在响应中设置cookie,而不是手动设置API的域,你可以省略它,浏览器将自动用域填充它。
要处理CORS并让JS成功发送cookie,您必须在cookie中设置
SameSite=None
和Secure
属性,并通过https提供API(我使用了ngrok使其简单化)。像这样
我建议您也阅读使用
localStorage
和document.cookie
之间的区别,这是我遇到的问题之一。希望这个有用。