Iris 中 session 默认未启用,需手动调用 app.Use(session.Handler()) 注册中间件且必须在路由前;存用户 ID 时只存最小标识并显式调用 sess.Save();校验登录应封装为中间件,登出必须用 sess.Destroy() 彻底清除。

Session 在 Iris 中默认不启用,必须手动配置
Iris 的 session 功能不是开箱即用的,iris.New() 创建的 app 默认没有 session 支持。不配置就直接调 ctx.Session().Set(),运行时会 panic:「session is not registered」。这不是 bug,是设计选择——Iris 把 session 当作可插拔中间件,由你决定是否启用、用哪种存储后端。
启用 session 的核心是调用 app.Use(session.Handler()),且必须在注册路由前执行。常见错误是把它放在 app.Get(...) 之后,导致后续 handler 拿不到 session 实例。
实操建议:
- 使用内存存储(开发调试):
session.Handler()不传参即可,默认用memstore - 生产环境务必换为持久化后端,比如 Redis:
session.Handler(redis.New( /* config */ )) - session cookie 默认无
HttpOnly和Secure,需显式设置:session.Handler().Cookie("mysession", session.Config{HttpOnly: true, Secure: true})
登录成功后怎么存用户 ID 到 Session
存数据本身很简单,但关键在于「存什么」和「怎么存更安全」。不要存完整用户对象或密码字段,只存最小必要标识,比如 user_id 或 session_token。Iris 的 session 接口是键值对形式,类型擦除,所以存之前最好做类型断言或统一转 string。
示例代码片段(登录 handler):
func loginHandler(ctx iris.Context) {
// ... 验证用户名密码
userID := 123 // 假设查库得到
sess := sessions.Default(ctx)
sess.Set("user_id", userID) // 自动序列化 int
err := sess.Save()
if err != nil {
ctx.StatusCode(500)
ctx.WriteString("session save failed")
return
}
ctx.Redirect("/dashboard", 302)
}注意:sessions.Default(ctx) 是获取当前请求绑定的 session 实例,必须在 session.Handler() 注册后才有效;sess.Save() 必须显式调用,否则写入不会持久化到 store。
如何在其他 handler 中检查登录状态
判断用户是否已登录,本质就是看 session 里有没有有效的 user_id。但要注意两个易错点:一是 key 不存在时 sess.Get("user_id") 返回 nil,不是零值;二是即使有值,也要校验其类型和有效性(比如是否为正整数)。
推荐写法(中间件形式):
func authMiddleware(ctx iris.Context) {
sess := sessions.Default(ctx)
userID := sess.Get("user_id")
if userID == nil {
ctx.StatusCode(401)
ctx.WriteString("unauthorized")
return
}
// 类型断言确保是 int 或 uint
if id, ok := userID.(int); ok && id > 0 {
ctx.Values().Set("user_id", id) // 向下游传递
ctx.Next()
} else {
ctx.StatusCode(401)
ctx.WriteString("invalid session")
}
}然后在受保护路由上使用:app.Get("/dashboard", authMiddleware, dashboardHandler)。
补充说明:
- 不要在每个 handler 里重复写校验逻辑,封装成中间件复用
- session 过期时间由
session.Config.Expires控制,默认 24 小时,建议按业务调整 - 如果用了 Redis store,过期时间还依赖 Redis 的 TTL 设置,要保持两端一致
退出登录时必须显式销毁 Session
sess.Destroy() 不只是清空数据,它还会删除服务端 store 中的记录,并让客户端 cookie 失效(通过设置过期时间为过去时间)。漏掉这步,用户关浏览器再打开可能仍能访问受保护页面——因为 cookie 还在,服务端 session 也还在。
正确登出 handler 示例:
func logoutHandler(ctx iris.Context) {
sess := sessions.Default(ctx)
sess.Destroy() // 关键:清除服务端 + 失效客户端 cookie
ctx.Redirect("/", 302)
}注意:sess.Clear() 只清空当前 session 数据,但不删除 session ID 对应的 store 记录,也不让 cookie 失效,不能代替 Destroy()。
另外,如果前端用了 JWT 配合 session(比如把 token 存在 session 里),登出时还要额外处理 token 黑名单或前端清理 localStorage,这部分 Iris 不管,得你自己补。


















