secure和httponly设为false等于主动放弃安全防护,secure=false使cookie在http中明文传输易被劫持,httponly=false则允许javascript读取敏感凭证引发xss窃取;二者仅在本地无https调试时可设false,其余场景必须为true。

为什么SetCookie的secure和httpOnly不能随便设为false
这两个参数不是“可选开关”,而是安全边界的硬性控制点。设成false等于主动放弃防护层,尤其在生产环境极易被利用。
常见错误现象:登录后用户 token 被 XSS 脚本窃取、HTTP 页面下 Cookie 被中间人劫持、前端 JS 读取到敏感凭证后误传至第三方。
-
secure = true时,浏览器只在 HTTPS 请求中发送该 Cookie;若服务已启用 TLS(如 Nginx 反代 HTTPS),但这里写成false,Cookie 就会在 HTTP 请求中明文暴露 -
httpOnly = true阻止 JavaScript 访问,比如document.cookie拿不到值;设为false后,任意注入的脚本都能读取并外发auth_token - 本地开发调试时用
localhost且无 HTTPS,secure必须为false,否则 Cookie 根本不会被浏览器保存——这是唯一合理设false的场景
domain 和 path 配不匹配会导致 Cookie 无法删除
删除 Cookie 不是“覆盖写空值”那么简单,它依赖浏览器按完全一致的 domain + path + secure + httpOnly 四元组匹配旧记录。任一字段对不上,新 Set 的“删除指令”就失效。
典型问题:登录时设了 c.SetCookie("token", "abc", 3600, "/", "example.com", true, true),登出时却写成 c.SetCookie("token", "", -1, "/", "www.example.com", true, true) —— 域名从 example.com 变成 www.example.com,浏览器认为这是另一个 Cookie,原 token 仍在。
- 多子域共享(如
a.example.com和b.example.com)必须统一设domain为.example.com(注意开头的点) -
path默认是/,但如果登录接口在/api/v1/login,而你设了path为/api/v1,那首页/就读不到这个 Cookie - 登出逻辑里删 Cookie,务必复用和设置时**完全相同的**
domain、path、secure、httpOnly
maxAge 设为负数不等于“立即消失”,而是触发浏览器清理机制
maxAge = -1 是标准做法,但它的实际效果取决于浏览器行为:不是秒级清除,而是标记为“过期”,下次页面刷新或请求时才真正丢弃。这中间存在时间窗口,尤其在单页应用(SPA)中容易被忽略。
更隐蔽的问题:某些浏览器(如 Safari)对频繁 Set/Delete 同名 Cookie 有节流策略,连续调用多次可能只生效最后一次。
-
maxAge = 0表示“忽略 Max-Age 字段”,等同于会话 Cookie(关闭浏览器即失效),不是删除 maxAge (如 <code>-1)才真正触发删除逻辑,但需配合正确domain/path- 若要确保敏感 Cookie 立即不可用,除了 Set 删除,还应在服务端立即废止对应 token(如 Redis 中 del session key)
用 Cookie 方法读取前,必须检查 err
c.Cookie("token") 返回 (string, error),错误类型包括 http.ErrNoCookie(客户端根本没带)和解析失败(如被篡改、base64 解码异常)。直接用返回值而不判 err,会导致 panic 或逻辑错乱。
真实踩坑场景:攻击者手动构造请求头 Cookie: token=; path=/,此时 c.Cookie("token") 返回空字符串 + nil error,但业务代码误以为“token 存在且为空”,放行鉴权。
- 永远先判断
err != nil,再处理cookie值 - 对空字符串做显式校验:
if cookie == "" || err != nil才算未认证 - 若需防御篡改,不要只依赖 Cookie 值本身,应结合签名(如
SetSecureCookie第三方封装)或服务端 session lookup
关键点始终落在:Cookie 参数不是孤立配置项,它们彼此约束、共同构成一条信任链。少一个 . 在 domain,或漏一次 err 判断,都可能让整个认证流程形同虚设。











