go语言设cookie必须用http.setcookie而非拼字符串,否则因未编码值、时间格式错、多cookie拼接不当致浏览器静默丢弃;删除需完全匹配name/path/domain/secure/samesite;httponly和secure是安全必需项,缺一不可。

Go 语言里不能靠拼字符串设 Cookie,必须用 http.SetCookie;不配 HttpOnly 和 Secure 就等于把 session ID 暴露在前端可读、HTTP 明文传输的危险境地。
为什么直接写 Set-Cookie 头会失败
很多人试过 w.Header().Set("Set-Cookie", "name=value; Path=/; Max-Age=3600"),结果浏览器根本不存。原因有三个:
-
Value里的特殊字符(如空格、中文、=)没做 URL 编码,浏览器静默丢弃 -
Max-Age或Expires格式不对(比如传了字符串时间),不同浏览器解析行为不一致 - 多个 Cookie 必须分多行
Set-Cookie,手动拼接容易出错或被合并成一个无效头
正确做法永远是构造 *http.Cookie,再交给 http.SetCookie(w, cookie) —— 它自动处理编码、时间格式、多 Cookie 分隔,且值传原始字符串即可,不用提前 url.QueryEscape。
删除 Cookie 必须完全匹配原始设置参数
删 Cookie 不是“设个 MaxAge=0”就完事。浏览器只清除那些 Name、Path、Domain、Secure、SameSite 全部一致的条目。
- 当初设的是
Path="/admin",删的时候用Path="/"→ 无效 - 开发时设了
Domain="localhost"(错误!localhost不被浏览器视为合法 Domain)→ 删不掉 - 生产环境用了 HTTPS,但删的时候
Secure=false→ 浏览器忽略该删除指令 - 正确删除姿势:
MaxAge=0+ 所有字段跟当初设置时一模一样,包括Path和Secure
gorilla/sessions 的 Save() 不是可选项
用 github.com/gorilla/sessions 时,常见错误是写了 session.Values["user_id"] = 123 就以为完事了。实际上:
- 所有修改都只在内存副本里,不调
session.Save(r, w)→ 前端收不到新 Cookie,服务端下次也读不到更新 - 登出时只清
session.Values不调Save()→ Cookie 还活着,旧 session ID 仍可复用 - 密钥长度必须 ≥32 字节,否则启动报
key must be 32 bytes long;本地调试可用cookiestore.NewCookieStore([]byte("...")),但生产务必换redisstore
HttpOnly 和 Secure 是上线前必须确认的开关
这两个字段不是“增强项”,而是基础防线:
-
HttpOnly: true→ 防 XSS:JS 脚本无法读取document.cookie,拿不到 session ID -
Secure: true→ 防中间人:仅 HTTPS 传输,HTTP 下不发送;本地开发可临时关,但代码里建议用配置控制,上线自动开启 -
SameSite: http.SameSiteLaxMode→ 缓解 CSRF:跨站 GET 请求不带 Cookie,POST 表单提交默认带(Lax 模式下)
漏掉任一者,攻击者可能通过 XSS 窃取 token,或在 HTTP 页面里伪造请求重放 session ID。这些细节不验证,线上就表现为「登录后刷新掉登」「登出后还能访问私有接口」——问题难复现,排查极耗时。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











