iris中写cookie应使用ctx.setcookie而非http.setcookie,因其自动处理响应头与上下文同步;读取应优先用ctx.cookies().get,它自动解码且兼容格式;敏感数据须自行加密(如gorilla/securecookie),而非常规cookie存储。

写 Cookie:用 ctx.SetCookie 而不是 http.SetCookie
直接调用标准库 http.SetCookie 会绕过 Iris 的上下文生命周期管理,导致 Cookie 在重定向或中间件链中丢失。Iris 提供了封装好的 ctx.SetCookie,它自动处理响应头、编码和上下文同步。
常见错误是漏设 Path 或误用 MaxAge 单位(单位是秒,不是毫秒):
-
Path必须显式设为"/"才能在全站读取,否则默认只作用于当前路径前缀 -
MaxAge设为负数(如-1)表示“会话级 Cookie”,浏览器关闭即失效 -
HttpOnly: true阻止 JS 访问,防 XSS;Secure: true强制仅 HTTPS 传输(生产环境必须开)
示例:
app.Get("/login", func(ctx iris.Context) {
ctx.SetCookie(&http.Cookie{
Name: "auth_token",
Value: "abc123",
Path: "/",
MaxAge: 3600, // 1小时
HttpOnly: true,
Secure: true, // 开发时若无 HTTPS,先设 false
SameSite: http.SameSiteLaxMode,
})
ctx.JSON(iris.Map{"ok": true})
})
读 Cookie:优先用 ctx.Cookies().Get,别手动解析 ctx.Request().Header.Get("Cookie")
Iris 的 ctx.Cookies().Get 自动解码 URL 编码、处理重复键、兼容旧版浏览器的分号分隔格式;而手动解析容易漏掉空格、转义字符或被伪造 Cookie 干扰。
注意两个典型陷阱:
- 如果 Cookie 是
HttpOnly,JS 无法读取,但 Iris 后端仍可正常Get—— 这是预期行为,不是 bug - 若值含特殊字符(如中文、+ 号),
Get会自动解码;但如果你用ctx.Request().Cookie(name),它不自动解码,需手动调url.QueryUnescape - 不存在的 Cookie 返回空字符串,不是 error,所以别用
err != nil判断是否存在
安全读取建议:
token := ctx.Cookies().Get("auth_token")
if token == "" {
ctx.StatusCode(401)
ctx.JSON(iris.Map{"error": "missing auth_token"})
return
}
本地存储加密:Iris 不内置加密,得自己套一层 securecookie 或 gob + crypto/aes
Iris 的 Cookie 值默认明文传输(即使 Secure 也只是保证 TLS 通道加密),服务端收到后也以明文存在内存里。要防篡改或敏感信息泄露,必须自行加密/签名。
推荐组合:gorilla/securecookie(轻量、成熟、专为 Cookie 设计):
- 它不加密内容,而是对值做 HMAC 签名(防篡改),可选加 AES 加密(防窥探)
- 密钥必须保密且定期轮换;硬编码在代码里或配置文件中都不安全,应从环境变量或 secret manager 加载
- 避免用
time.Now().Unix()做 salt —— 它会导致每次生成不同 hash,验证失败
简短集成示意(需 go get github.com/gorilla/securecookie):
var cookieHandler = securecookie.New(
securecookie.GenerateRandomKey(32), // auth key
securecookie.GenerateRandomKey(32), // encrypt key
)
app.Use(func(ctx iris.Context) {
// 读取并解密
if cookie, err := ctx.Request().Cookie("encrypted_data"); err == nil {
var data map[string]string
if err := cookieHandler.Decode("encrypted_data", cookie.Value, &data); err == nil {
ctx.Values().Set("decrypted", data)
}
}
ctx.Next()
})
为什么不用 ctx.Session 替代 Cookie 加密?
Session 默认把数据存在服务端(内存/Redis),只通过 Cookie 传一个随机 Session ID,天然比存敏感数据到客户端 Cookie 更安全。但要注意:
- Session ID 的 Cookie 本身仍需设
HttpOnly、Secure、SameSite,否则可能被窃取 - 如果 Session 存 Redis,务必设置 TTL(如
Expires: 24*time.Hour),避免堆积 - 不要在 Session 里存大量数据(比如整个用户对象),会放大网络和序列化开销;只存必要 ID 或 token,再按需查 DB
真正需要“本地存储加密”的场景其实很少:多数时候你该用 Session + JWT(服务端无状态)或短期 Token(如一次性邮箱验证链接),而不是把加密逻辑塞进 Cookie 处理流程里。











