iris 的 mvc 模式不自动注入 session,必须手动调用 sess.start(ctx) 获取;controller 中声明 *sessions.session 字段始终为 nil,需在 handler 或 beginrequest 中显式赋值。

直接结论:Iris 的 MVC 模式本身不自动注入 Session,必须手动从请求上下文获取,且不能依赖字段自动绑定 —— 这是绝大多数新手踩坑的根源。
为什么 Controller 字段里声明 *sessions.Session 不生效
Iris 的 MVC 激活机制(BeforeActivation)只对特定类型做自动注入,比如 iris.Context、http.ResponseWriter、*http.Request,但 *sessions.Session 不在默认注入列表中。即使你在 Controller 结构体里写:
type UserController struct {
Session *sessions.Session // ❌ 这个字段始终为 nil
}
运行时访问 c.Session.Get("user_id") 会 panic。Iris 不会在每次请求时帮你调用 sess.Start(ctx) 并赋值给该字段。
正确获取 Session 的两种方式
必须显式从 iris.Context 出发,通过 session 实例调用 .Start():
- 方式一:在每个 handler 方法内调用(最常用、最可控)
func (c *UserController) GetProfile(ctx iris.Context) {
sess := sess.Start(ctx) // sess 是全局 *sessions.Sessions 实例
userID := sess.GetInt64("user_id")
if userID == 0 {
ctx.StatusCode(401)
ctx.WriteString("not logged in")
return
}
ctx.JSON(map[string]interface{}{"id": userID})
}
- 方式二:在
BeginRequest中注入到自定义字段(需配合指针接收)
type UserController struct {
Ctx iris.Context
Sess *sessions.Session `inject:""` // 注意:仅当使用 inject 标签 + 自定义依赖注册时才有效
}
<p>func (c *UserController) BeginRequest(ctx iris.Context) {
c.Ctx = ctx
c.Sess = sess.Start(ctx) // ✅ 手动赋值,后续方法可直接用 c.Sess
}</p>
注意:`inject:""` 不是 Iris 原生支持,需额外调用 app.MVC(...).Register(...) 注册依赖,实际项目中不如方式一简洁可靠。
sessions.Config 关键参数影响 Session 安全与行为
初始化 session 实例时,以下配置项直接影响客户端体验和安全性:
-
Cookie:设置 Cookie 名称,默认iris_session_id,建议改为自己项目的唯一标识,如"myapp_sid" -
Expires:Session 过期时间,单位是time.Duration;设为0表示浏览器关闭即失效(会话级) -
AllowReclaim:是否允许回收已过期但未被 GC 清理的 session ID;生产环境建议设为false防止 session fixation -
Secure和HTTPOnly:必须在 HTTPS 环境下设Secure: true;HTTPOnly: true是默认值,别关
示例:
sess := sessions.New(sessions.Config{
Cookie: "myapp_sid",
Expires: 24 * time.Hour,
AllowReclaim: false,
Secure: true, // 仅限 HTTPS
HTTPOnly: true,
})
Session 数据读写必须成对使用 Get/Set,且类型要严格匹配
Iris 的 Session 方法是类型安全的,SetString("key", "val") 后必须用 GetString("key") 读,混用会导致返回零值或 panic:
-
SetString/GetString -
SetInt/GetInt(注意:不是GetInt64,除非你显式用了SetInt64) -
SetBoolean/GetBoolean -
SetFlash/GetFlash:仅在下一次请求有效,适合登录跳转后提示
错误示范:
sess.SetInt("count", 123)
val := sess.GetString("count") // ❌ 返回空字符串,不是 "123"
Session 在 Iris MVC 中不是“开箱即用”的魔法字段,它的生命周期完全由你控制 —— 什么时候 start、读什么类型、何时清理,都得亲手写清楚。最容易忽略的是:没检查 sess.Start(ctx) 返回的 session 是否真的有数据,就直接 .GetXXX,结果静默失败。











