You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gin框架设置Cookie无法被浏览器保存问题求助

问题描述

我第一次使用Gin框架构建API,目前遇到浏览器无法保存Cookie的问题:在开发者工具中能看到响应的Set-Cookie头及正确值,且该请求的Cookie标签下也能看到Cookie,但浏览器的Application->Storage->Cookies中并未保存这些Cookie。已尝试过两个StackOverflow方案,但均未解决问题。

后端代码

router.Use(cors.New(cors.Config{
        AllowMethods:     []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"},
        AllowHeaders:     []string{"Origin", "Content-Length", "Content-Type"},
        MaxAge:           12 * time.Hour,
        AllowAllOrigins:  true,
        AllowCredentials: true,
    }))

router.POST("/users/login", server.LoginUser)
func (server *Server) LoginUser(ctx *gin.Context) {
        ...
    ctx.SetCookie("access_token", accessToken, 3600, "/", "localhost", false, true)
    ctx.SetCookie("refresh_token", refreshToken, 3600, "/", "localhost", false, true)

    ctx.JSON(http.StatusOK, gin.H{"ok": true, "payload": rsps})

}

前端代码

const login = async () => {
    const res = await fetch("http://localhost:3000/users/login", {
      method: "POST",
      body: JSON.stringify({ username, password }),
    });
    const data = await res.json();
    console.log(data);
  };
  const handleFormSubmit = (e) => {
    e.preventDefault();
    login();
  };

  return (
    <div>
      <h1>Login Page</h1>
      <form onSubmit={handleFormSubmit}>
         ...
        <button type="submit">Login</button>
      </form>
    </div>
  );
解决思路

1. 前端fetch必须添加credentials: 'include'

跨域请求中,浏览器默认不会处理Cookie,必须显式开启凭证携带。修改前端代码:

const login = async () => {
    const res = await fetch("http://localhost:3000/users/login", {
      method: "POST",
      body: JSON.stringify({ username, password }),
      credentials: 'include', // 关键:允许携带和保存Cookie
      headers: {
        'Content-Type': 'application/json' // 补充JSON请求头,确保后端能解析请求体
      }
    });
    const data = await res.json();
    console.log(data);
  };

2. 调整后端CORS配置,避免AllowAllOrigins与AllowCredentials冲突

部分浏览器对AllowAllOrigins: true+AllowCredentials: true的组合兼容性差,建议明确指定允许的前端Origin,并暴露Set-Cookie头:

router.Use(cors.New(cors.Config{
        AllowMethods:     []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"},
        AllowHeaders:     []string{"Origin", "Content-Length", "Content-Type", "Authorization"},
        MaxAge:           12 * time.Hour,
        AllowOrigins:     []string{"http://localhost:5173"}, // 替换为你的前端实际运行地址
        AllowCredentials: true,
        ExposeHeaders:    []string{"Set-Cookie"}, // 确保前端能访问到Set-Cookie响应头
    }))

3. 配置Cookie的SameSite属性

跨域场景下,Cookie的SameSite属性需要设为None才能被浏览器保存。确保你的Gin版本≥v1.7.0(支持SameSite参数),修改SetCookie代码:

// 开发环境(HTTP):Secure设为false
ctx.SetCookie("access_token", accessToken, 3600, "/", "localhost", false, true, gin.SameSiteNoneMode)
ctx.SetCookie("refresh_token", refreshToken, 3600, "/", "localhost", false, true, gin.SameSiteNoneMode)

// 生产环境(HTTPS):Secure设为true
// ctx.SetCookie("access_token", accessToken, 3600, "/", "yourdomain.com", true, true, gin.SameSiteNoneMode)

本地开发注意:如果用HTTP协议,Chrome等浏览器会默认阻止SameSite=None的Cookie,需要在浏览器设置中临时关闭限制(地址栏输入chrome://flags/#same-site-by-default-cookies,将选项设为Disabled)。

4. 统一域名/端口

确保前端与后端的域名一致(比如都用localhost,不要混用localhost和127.0.0.1),Cookie的Domain设置要匹配当前域名。

5. 清除浏览器缓存

清除浏览器Application->Storage->Cookies下的所有现有Cookie,重启浏览器后重新测试。

内容的提问来源于stack exchange,提问作者Eyal Solomon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 05:25:31