Iris MVC中Cookie操作必须显式调用ctx.SetCookie()/GetCookie(),不支持结构体自动绑定;所有读写需在方法体内手动执行,且校验逻辑应置于中间件并调用ctx.StopExecution()终止流程。

Cookie写入必须显式调用ctx.SetCookie(),不能靠结构体字段自动绑定
很多人在Iris MVC控制器里写func(c *UserController) Get(ctx iris.Context, token string) {},指望框架从Cookie里自动提取token——这完全不会生效。Iris只对URL路径参数、查询参数、JSON/Form数据做自动绑定,Cookie必须手动读写。
所有Cookie操作都得在方法体内显式调用:ctx.SetCookie()、ctx.GetCookie()或ctx.RemoveCookie()。控制器里的Ctx iris.Context字段只是个空壳,不主动赋值就等于没用。
-
ctx.SetCookie(&http.Cookie{Name: "auth_token", Value: "abc123", Path: "/", MaxAge: 3600, HttpOnly: true, Secure: true})——注意MaxAge单位是秒,设为0表示会话级Cookie -
val := ctx.GetCookie("auth_token")返回string,如果不存在则为空字符串,不会panic - 要读带
HttpOnly或Secure标记的Cookie,前端AJAX请求必须配withCredentials: true,否则浏览器根本不会发过去
加密Cookie需用iris.CookieEncoding配置AES密钥,而非手写加解密逻辑
Iris内置了CookieEncoding机制,支持AES-GCM(推荐)或AES-CBC加密,不需要自己调crypto/aes封装。关键点在于:密钥必须固定且足够长(32字节),且不能硬编码在代码里。
正确做法是在初始化sessions.Sessions或注册全局Cookie中间件时统一配置:
立即学习“go语言免费学习笔记(深入)”;
- 启用加密:
iris.CookieEncoding(iris.CookieEncodingConfig{Key: []byte("32-byte-aes-key-must-be-exact")}) - 该配置会影响所有
SetCookieKV、SetCookie和sessions写入的Cookie值,但GetCookie会自动解密,无需额外处理 - 密钥泄露=Cookie全部可伪造,务必通过环境变量注入,比如
os.Getenv("COOKIE_ENCRYPTION_KEY") - 不要混用加密/未加密Cookie:同一域名下既有加密又有明文Cookie,容易引发解析混乱或静默失败
子域名共享加密Cookie必须设CookieDomain: ".example.com",否则浏览器不发送
本地开发时localhost或127.0.0.1能读到Cookie,一上生产(如admin.example.com→api.example.com)就失效,大概率是CookieDomain没设对。
浏览器对Domain字段极其严格:Domain: "example.com"只匹配精确域名;Domain: ".example.com"(开头带点)才允许所有子域名读写。
- 必须显式配置:
iris.CookieEncoding(...).CookieDomain(".example.com").CookiePath("/").CookieSecure(true).CookieHTTPOnly(true) -
CookieSecure: true在HTTPS下强制生效,HTTP环境下会被浏览器忽略——测试时若用HTTP,需临时设为false,但上线前必须改回 - 前端跳转(如链接)时,若
SameSite默认为Lax,跨站GET请求可能不携带Cookie;必要时设CookieSameSite(http.SameSiteNoneMode)并确保CookieSecure: true
中间件里校验加密Cookie必须用ctx.GetCookie(),且失败后立即ctx.StopExecution()
Cookie校验逻辑不属于控制器生命周期,不能塞进BeforeActivation或BeginRequest——那只是路由注册阶段,不参与真实请求。必须挂到app.Use()或Party.Use()上。
典型错误是校验失败后只写响应却不中断流程,导致业务handler仍被执行:
- 正确流程:
token := ctx.GetCookie("auth_token")→ 解密验证 → 失败则ctx.StatusCode(401)+ctx.WriteString("unauthorized")+ctx.StopExecution() - 漏掉
ctx.StopExecution()会导致后续中间件和控制器继续运行,可能查DB、改状态,造成越权 - 不要在中间件里调
ctx.Next()后再校验——那时请求已进入下游,拦截无意义 - 若多个控制器共用同一套逻辑,中间件比每个
BeginRequest里重复写更可靠,也避免遗漏
加密本身不解决会话劫持,HttpOnly防XSS、Secure防中间人、SameSite防CSRF,这些标记一个都不能少;而密钥轮换、token绑定用户agent/IP、服务端tokenVersion校验,才是真正的纵深防御点。


















