expires_in 控制服务端 Session 数据存活时长(单位秒),不影响客户端 Cookie 过期;cookie_max_age 才决定浏览器 Cookie 生命周期,二者可分离但需协调,否则导致会话不一致。

session.yml 的 expires_in 控制 Session 过期,但不等于 Cookie 过期
Buffalo 的 Session 生命周期由两层控制:服务端存储(如内存或数据库)的过期时间,和客户端 Cookie 的 Max-Age/Expires 属性。二者默认联动,但可分离。expires_in 字段只影响服务端 Session 数据的存活时长(单位秒),比如设为 3600 表示 1 小时后服务器自动丢弃该会话数据。
它不会强制浏览器删除 Cookie——除非你同时配置了 cookie_max_age 或显式调用 c.Session().Destroy()。
-
expires_in必须是整数,不能写"1h"或time.Hour - 若设为
0,Session 在服务端永不过期(不推荐,有内存泄漏风险) - 若设为负数(如
-1),Buffalo 会 panic:“invalid expires_in value” - 修改后必须重启
buffalo dev,热重载不生效
cookie_max_age 和 secure 共同决定浏览器是否保留 Cookie
Cookie 的实际生命周期由 cookie_max_age(单位秒)控制,它直接映射到 HTTP 响应头的 Max-Age。这个值独立于 expires_in,可以更短(比如 Session 存 24 小时,但 Cookie 只存 30 分钟),但不能更长——否则用户关浏览器再打开,Cookie 还在,但服务端已删 Session,导致 c.Session().Get() 返回 nil。
开发时务必确认:secure: false,否则浏览器拒绝保存 Cookie(因非 HTTPS);http_only: true 应保持开启,禁用它会让 JS 读取到 Session ID,引发 XSS 风险。
-
cookie_max_age: 1800→ Cookie 30 分钟后自动过期并从浏览器清除 -
cookie_max_age: 0→ Cookie 变成“会话 Cookie”,关闭浏览器即失效 -
secure: true在 HTTP 环境下会导致 Cookie 不写入,且无错误提示,只表现为c.Session().Get()总是空 -
domain字段留空即可,填错(如带http://)会导致 Cookie 被浏览器静默丢弃
手动销毁 Session 比依赖过期更可靠
靠时间自动过期存在窗口期:用户可能在过期前最后一秒发请求,服务器仍认为有效;而浏览器 Cookie 尚未清除,下次请求又带上旧 ID,可能触发新 Session 初始化(取决于 store 实现)。生产环境建议主动清理。
审查 Remix v2 代码中的 v1 形态 meta 导出(v2 中为破坏性变更),cookie 安全漏洞(httpOnly、secure、密钥轮换),认证门位于错误层级,以及其他
登出逻辑必须调用 c.Session().Destroy(),它会:清空服务端 Session 数据、删除客户端 Cookie(通过 Set-Cookie + Max-Age=0)、并让后续 c.Session().Get() 立即返回 nil。
- 别只删 key:
c.Session().Delete("user_id")不等于登出,Session ID 依然有效 -
c.Session().Clear()只清键值,不销毁 Session ID,也不删 Cookie -
c.Session().Destroy()后无需再调Save(),它内部已处理 - 若用数据库 store(如 PostgreSQL),
Destroy()会执行 DELETE 语句,不是软删
测试时注意:内存 store 不支持 expires_in 自动清理
Buffalo 默认用 memstore,它的 expires_in 仅在每次 Get() 时检查是否超时,不会后台定时扫描清理。这意味着:即使过了期,只要没人访问该 Session,它就一直占内存。
如果你跑的是长期运行的开发服务,或压测中创建大量 Session,得自己加监控或换 store(如 redis)。临时方案是定期调用 store.Clean(time.Now()),但 Buffalo 没暴露该接口,需改源码或换 pop-based store。
最易被忽略的一点:所有时间配置都基于服务器本地时间,如果部署在 Docker 容器里没同步宿主机时区,expires_in 可能比预期快或慢几十分钟——别只查代码,先 docker exec -it app date 看系统时间对不对。










