Iris Session 默认不启用,需手动配置中间件:调用 sess.Handler() 并通过 app.Use() 挂载;Session 实例须复用,读写必须每次从 ctx 获取;登出应调用 sess.Destroy() 而非仅删 key。

Session 默认不启用,必须手动配置中间件
Iris 默认不自动启用 Session,iris.Sessions 只是构造器,不注册中间件。漏掉 Use 或 UseGlobal 就会发现 ctx.Session() 返回 nil,所有 Set/Get 都静默失败。
正确做法是显式挂载:
sess := sessions.New(sessions.Config{
Cookie: "my_session",
Expires: 24 * time.Hour,
})
app.Use(sess.Handler()) // 关键:必须调用 Handler() 并 Use常见错误包括:
• 直接 sess.Start(ctx) 而不挂中间件
• 把 sess 当成全局单例反复 New(应复用同一实例)
• Cookie 名含空格或特殊字符导致浏览器拒存
Session ID 生成与存储位置影响跨请求一致性
Iris Session 默认用内存存储(sessions.Memory),重启进程后全部丢失;若用 Redis 后端,需确保 Store 实例被复用,且连接未超时。
关键参数控制行为:
-
CookieHTTPOnly: true(默认)→ JS 无法读取,防 XSS 窃取 -
CookieSecure: true→ 强制 HTTPS 下发送,本地开发需设为 false -
CookieSameSite: http.SameSiteStrictMode→ 影响跨站表单提交时的 Session 携带
示例(Redis 存储):
由 ReMe 驱动的记忆管理系统,支持跨会话记忆持久化、自动应用用户偏好以及智能上下文压缩...
store := redis.New(redis.Config{
Network: "tcp",
Addr: "127.0.0.1:6379",
})
sess := sessions.New(sessions.Config{
Cookie: "my_session",
Store: store,
})读写 Session 必须通过上下文获取实例
不能在 handler 外直接调用 sess.Start(ctx) 或缓存 session.Session 对象——它绑定当前请求生命周期。每次都要从 ctx 拿:
func loginHandler(ctx iris.Context) {
sess := sessions.Get(ctx) // 正确:从 ctx 动态获取
sess.Set("user_id", 123)
sess.Set("logged_in", true)
ctx.JSON(iris.Map{"ok": true})
}容易踩的坑:
- 在 goroutine 中异步调用
sess.Set→ 上下文已结束,写入无效甚至 panic - 用
sess.ID()做用户标识 → ID 是随机字符串,不代表用户身份,应存"user_id"这类业务字段 - 对 map 类型值直接
sess.Set("data", map[string]int{"a": 1})→ Iris 底层序列化依赖encoding/gob,需提前gob.Register自定义类型
登出要销毁 Session,不能只删 key
仅 sess.Delete("user_id") 不等于登出,Session ID 仍有效,其他 key 也还在。真正登出需调用 sess.Destroy():
func logoutHandler(ctx iris.Context) {
sess := sessions.Get(ctx)
sess.Destroy() // 删除服务端数据 + 设置 Cookie 过期
ctx.Redirect("/login", iris.StatusFound)
}注意:
• Destroy() 会立即清除所有数据,不可恢复
• 若前端有多个 tab 共享同一 Session,一个 tab 登出会导致其他 tab 的后续请求丢失 Session
• 某些代理或 CDN 可能缓存了 Set-Cookie 响应头,导致 Destroy 失效,需检查响应头是否含 Cache-Control: no-store
Session 的有效期、存储后端、跨域策略和销毁时机,这几个点任意一个配错都会让状态“看起来没保存”或“登不出”。别假设默认值适合生产环境。

















