【发布时间】:2022-01-11 19:39:04
【问题描述】:
我有一个用 Go 编写的后端,托管在 Heroku 上,我们称之为 https://foo.herokuapp.com。我有一个托管在不同域上的前端,我们称之为https://ui.example.com。
后端 API 有一个端点 /api/user/login,它以 cookie 的形式发回一个 JSON Web Token,如下所示:
http.SetCookie(w, &http.Cookie{
Name: "token",
Value: token, // the JWT
HttpOnly: false, // for testing, set to true later once I fix this
MaxAge: int(time.Hour * 24 * 3),
Expires: time.Now().UTC().Add(time.Hour * 24 * 3),
Path: "/",
Secure: true,
SameSite: http.SameSiteNoneMode,
})
这些是我在服务器上的 CORS 设置。
crossOrigin := cors.New(cors.Options{
AllowedOrigins: []string{allowedOrigin},
AllowCredentials: true,
AllowedMethods: []string{http.MethodGet, http.MethodPost, http.MethodPut},
})
前端向后端发出请求,如下所示。
const endpoint = "/api/user/login/"
fetch(host + endpoint, {
method: "POST",
credentials: 'include',
body: JSON.stringify({
email,
password
})
}).then((response) => console.log(response))
.catch((err) => console.log(err));
问题: 现在这个 cookie 实际上在我的浏览器的网络选项卡中可见。
但 cookie 不存在于应用程序选项卡(或存在 cookie 的 Firefox 中的存储选项卡)中。浏览器没有保存 cookie,导致后续请求失败,因为 cookie 中的令牌在处理实际请求之前已经过验证和解码。
在另一个相关的线程中,我了解到 Heroku 在到达我的应用程序之前终止了 SSL。并且,因此无法为非 SSL 流量设置安全 cookie。那里的解决方案建议信任X-Forwarded-For 中的方案。我使用https://github.com/gorilla/handlers 包启用了它,如下所示。
// srv is my actual handler
// crossOrigin is the CORS middleware
// finally wrapped by ProxyHeaders middleware
handlers.ProxyHeaders(crossOrigin.Handler(srv))
但这是行不通的。
我阅读了许多主题/博客。到目前为止没有任何效果。我做错了什么?
【问题讨论】:
-
这不能解决您的问题,但
time.Hour是一小时内的纳秒数(不是秒数)!Cookie.MaxAge应该是秒数,所以应该是:MaxAge: int(time.Hour.Seconds() * 24 * 3) -
另外:设置 MaxAge xor Expires(首选 MaxAge)。
-
@icza 不错,谢谢!
-
@Volker 是的,我读到 MaxAge 现在应该是首选。我添加了两者,因为我最初不确定。
标签: http go heroku cookies jwt