maxage参数表示cookie从设置时刻起多少秒后失效,填正数为存活秒数,填0视为会话cookie,填负数(如-1)立即删除;必须与原始设置的path、domain、secure、httponly完全一致才能成功删除。

SetCookie 的 maxAge 参数到底怎么填
maxAge 是控制 Cookie 生存时间的唯一可靠方式,它不是“过期时间戳”,而是“从设置时刻起多少秒后失效”。填 0 或正数时,浏览器按秒计算;填负数(如 -1)则立即删除——这和 Expires 头语义不同,也比手动设过去时间更稳妥。
常见错误:用 time.Now().Add(30 * time.Second).Unix() 算出时间戳再传给 maxAge,结果 Cookie 持续存在或根本没生效。Gin 的 c.SetCookie 不接受时间戳,只认秒数。
-
maxAge = 30→ 浏览器 30 秒后自动丢弃 -
maxAge = 0→ 大部分浏览器视作“会话 Cookie”,关闭标签页即失效(但不保证) -
maxAge = -1→ 强制立刻删除,是登出场景的标准写法
path 和 domain 必须和设置时完全一致才能删除
Cookie 的匹配是严格基于 name + path + domain 三元组的。删 Cookie 时如果 path 写成 "/admin",而当初是用 "/" 设置的,那这次删除就无效——浏览器会认为这是另一个 Cookie。
同理,domain 如果当初设的是 "example.com",删的时候写成 "www.example.com" 或留空(""),也会失败。生产环境建议统一用根域名(如 "example.com"),避免子域差异。
- 设置时用了
"/",删除时也必须用"/" - 设置时
domain是"example.com",删除时不能省略或改写 - 本地开发用
"localhost",上线后必须同步改成真实域名
secure 和 httpOnly 标志影响删除行为
这两个布尔参数不是“可选装饰”,而是 Cookie 属性的一部分。如果原始 Cookie 带了 httpOnly=true,删的时候也得保持 true,否则浏览器可能忽略该删除指令——尤其在 Chrome 95+ 后更严格。
secure 更容易踩坑:HTTP 环境下设了 secure=true,浏览器直接拒绝存储;反过来,HTTPS 环境下删 Cookie 却传 false,也可能导致删除失败。
- 原始设置是
c.SetCookie("token", "xxx", 3600, "/", "example.com", true, true) - 对应删除必须是
c.SetCookie("token", "", -1, "/", "example.com", true, true) - 开发调试时,HTTP 环境下
secure一律设false,别硬编码true
为什么有时候删了还出现在后续请求里
不是 Gin 没删干净,而是浏览器没执行删除——最常见原因是路径或域名不匹配,或者前端 JavaScript 用 document.cookie 又写回了一个同名但属性不同的 Cookie(比如漏了 HttpOnly)。这种情况下,服务端发的删除指令被浏览器判定为“不覆盖现有 Cookie”,于是静默忽略。
验证是否真删掉:别只看响应头,打开浏览器 DevTools → Application → Cookies,确认对应域名下该 key 已消失;同时抓包看响应头中 Set-Cookie: name=; Max-Age=0; Path=/; Domain=... 是否完整且参数一致。
复杂点在于,同一域名下多个路径、多个子域、多种 secure/httpOnly 组合的 Cookie 可能共存,删错一个就等于没删。











