首页 > 解决方案 > Cookie 未保存在浏览器中

问题描述

我正在使用 gorilla session 包来管理 cookie,但它们没有保存在浏览器中。服务器和前端在不同的域上运行,所以我认为这是一些 CORS 限制,因为如果我从 Postman 或从与服务器在同一域上提供的页面发出请求,cookie 正在保存并且一切正常。

我也使用 nginx 服务于前端,所以可能是缺少额外设置的问题。这是代码:

//settings for gorilla sessions
SessionStore = sessions.NewCookieStore([]byte(SessionKey))
SessionStore.Options = &sessions.Options{
    Secure: true,
    Path:   "/",
}

//settings for cors issues. github.com/rs/cors package

    c := cors.New(cors.Options{
            AllowedOrigins:   []string{"https://clientdomain.com"},
            AllowCredentials: true,
        })

//simplified process of saving cookie. All returned errors are nil
func SignIn(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    w.Header().Set("Access-Control-Allow-Origin", "https://clientdomain.com")
    w.Header().Set("Access-Control-Allow-Credentials", "true")
    session, err := SessionStore.Get(r, SessionName)
    err = session.Save(r, w)
}

以及简单的 nginx 配置。Nginx 在 docker 上工作,它全部部署在 heroku 上。我在本地尝试过,一切正常,所以这里可能是个问题,但我认为它来自 CORS 。

   server {
  listen $PORT default_server;

  location / {
    root   /usr/share/nginx/html;
    include  /etc/nginx/mime.types;
    try_files $uri $uri/ /index.html;
  }
}

浏览器不会在控制台中发送任何消息,它们只是不保存 cookie。

标签: gonginxcookiescross-domain

解决方案


首先,您可以尝试使用 Firefox 浏览器,因为它似乎是迄今为止唯一仍然允许 3rd 方 cookie 的浏览器。Google Chrome 84+ 对跨站点 cookie 处理有很大限制。

要使 3rd 方 cookie 在现代浏览器上工作,它必须满足 3 个条件:

  • 它通过安全的 HTTPS 协议发送。
  • 它有SameSite=None
  • 必须设置Secure标志

所以,让我们稍微修改一下你的后端:

SessionStore = sessions.NewCookieStore([]byte(SessionKey))
SessionStore.Options = &sessions.Options{
    Path:     "/",
    Secure:   true,
    SameSite: http.SameSiteNoneMode,
}

在前端,确保您的 ajax 请求始终与withCredentials

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

推荐阅读