Metabase 会话过期机制完全指南:MAX_SESSION_AGE、MB_SESSION_TIMEOUT 与 MB_SESSION_COOKIES 配置详解
2026/9/12 12:39:07 网站建设 项目流程

Metabase 会话过期机制完全指南:MAX_SESSION_AGE、MB_SESSION_TIMEOUT 与 MB_SESSION_COOKIES 配置详解

【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase

Metabase 的会话(Session)是登录态得以跨标签页、跨页面保持的核心机制,而如何让会话按预期过期、何时强制登出用户,直接关系到系统的安全性与用户体验。本文以 Metabase 官方文档 changing-session-expiration.md 为主体骨架,结合当前仓库的会话中间件、Cookie 处理与定时清理任务的源码实现,系统讲解会话过期相关的三组配置:绝对会话上限MAX_SESSION_AGE、不活跃超时MB_SESSION_TIMEOUT与强制会话 CookieMB_SESSION_COOKIES。读完本文,你将掌握每种过期方式的适用场景、精确的配置语法与参数取值范围,并理解它们在底层是如何协同生效的。

会话的生命周期:Metabase 如何维持登录态

当用户通过邮箱密码或 SSO 登录时,Metabase 会创建一个会话,使其在切换标签页、刷新页面的过程中保持登录状态。从 src/metabase/server/middleware/session.clj 的命名空间文档可以看到认证的两条主要路径:

  • 会话(Session)认证:登录成功后自动写入名为metabase.SESSION的 Cookie,该 Cookie 为 HttpOnly 属性,前端代码无法读取;全应用嵌入(full-app embedding)场景下则为metabase.EMBEDDED_SESSION。此外请求头X-Metabase-Session也可用于认证,此时两个 Cookie 会被忽略。
  • API Key 认证:通过X-Api-Key请求头匹配数据库中的 API Key,适用于服务端自动化调用场景,与会话过期机制无关。

会话可以通过以下三种方式结束,这也是本文后续三个章节的主题:

  1. 关闭浏览器(受 Cookie 类型与MB_SESSION_COOKIES影响);
  2. 达到绝对会话年龄上限MAX_SESSION_AGE,从登录时刻开始计时);
  3. 持续不活跃达到超时窗口MB_SESSION_TIMEOUT,从最后一次活动时刻开始计时)。

需要特别说明的是:手动清除浏览器 Cookie 或缓存会立即结束会话,这一行为不受上述任何设置的约束。

设定绝对会话上限:MAX_SESSION_AGE

语义与默认值

MAX_SESSION_AGE控制一个会话从登录时刻起最多可以存活多少分钟。例如用户打开了数百个标签页且数月未重启浏览器,只要达到MAX_SESSION_AGE就会被登出——即便登录时勾选了Remember me(记住我)复选框也无法豁免,因为该上限是强制性的。

  • 类型:整数
  • 默认值20160(即 14 天),见 src/metabase/cmd/resources/other-env-vars.md
  • 设置方式:仅支持环境变量。上述文档明确写道:MAX_SESSION_AGE只能通过环境变量设置,无法通过配置文件(config文件)修改。

配置示例

以分钟为单位设置自定义值,例如让会话在 24 小时后过期:

# 会话在 24 小时后过期 MAX_SESSION_AGE=1440 java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar

该设置对所有人一视同仁,不区分浏览器行为或活动模式。当安全策略要求用户按可预测的周期重新登录时(例如每 24 小时或每周强制重新认证一次),应使用此配置。

底层生效机制

MAX_SESSION_AGE在源码中的生效路径分为三层:

  1. Cookie 有效期:在 src/metabase/request/cookies.clj 中,会话 Cookie 的Max-Age默认值由(* 60 (config/config-int :max-session-age))计算(分钟换算为秒)。也就是说,即使浏览器不关闭,Cookie 本身也会在到达上限后过期。
  2. 服务端校验:在 src/metabase/server/middleware/session.clj 中,每次请求解析会话时会传入(config/config-int :max-session-age),由应用数据库查询判断会话是否已过期(详见 src/metabase/server/db.clj 中的会话用户信息查询)。
  3. 定时清理:Metabase 内置的 SessionCleanup 任务每天凌晨 2 点(cron 表达式0 0 2 * * ? *)运行一次,删除超出MAX_SESSION_AGE、超过自身expires_at、或超过不活跃阈值的会话记录,见 src/metabase/session/task/session_cleanup.clj。其底层 SQL 位于 src/metabase/session/db.clj。

注意MAX_SESSION_AGE不是空闲/不活跃超时。若将其设为 15 分钟,用户每 15 分钟就必须重新登录(或重新认证)一次,无论期间是否活跃。控制"不活跃多久后登出"应使用MB_SESSION_TIMEOUT

按不活跃时长登出:MB_SESSION_TIMEOUT

功能定位与授权前提

MB_SESSION_TIMEOUT控制会话在不活跃多长时间后结束。例如用户早上打开 Metabase,用了一小时,之后一整天都在其他工具中工作,一旦不活跃时间超过设定窗口就会被登出。

该功能属于Metabase 付费版(EE)特性:在 src/metabase/premium_features/settings.clj 中定义了enable-session-timeout-config?,并映射到特性令牌:session-timeout-config。对应地,测试 test/metabase/server/middleware/session_test.clj 验证了:未启用该付费特性时,即便设置了session-timeout,会话也不会因此过期

两种配置方式

方式一:管理员界面。进入Admin(管理后台)>Authentication(认证)>Overview(概览)页面配置。需要说明的是,界面中只能以**分钟(minutes)或小时(hours)**为单位指定超时时间。

方式二:环境变量。使用 JSON 格式的字符串,单位支持seconds(秒)、minutes(分钟)、hours(小时):

# 不活跃 2 小时后登出 MB_SESSION_TIMEOUT='{"amount":120,"unit":"minutes"}' java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar

环境变量相较界面配置多支持"unit":"seconds",这在与测试、自动化脚本对齐时更为灵活。

参数校验规则

从 src/metabase/request/settings.clj 的session-timeout设置定义可以确认以下规则:

  • 值必须是 JSON 对象,形如{"amount":120,"unit":"minutes"}unit只能是secondsminuteshours三者之一;
  • amount必须为正数(amount-must-be-positive),且不能达到 100 年(amount-must-be-less-than-100-years);
  • 校验失败时,通过 API 或界面设置会返回 HTTP 400,并附带明确的错误信息;环境变量方式下则记录警告并回退为nil(即不启用超时)。

此外,src/metabase/request/cookies.clj 中的session-timeout->seconds函数将所有单位统一换算为秒,并强制最小值 60 秒——这是为了防止管理员误设过短的时间导致用户把自己锁在门外。对应测试见 test/metabase/request/cookies_test.clj 与 test/metabase/request/settings_test.clj。

什么算"活跃"?

这一点直接影响实际效果,官方文档给出了两条关键行为:

  • 开启自动刷新(auto-refresh)的仪表盘即使在后台标签页中,也会持续产生请求,因此计入活跃,能不断刷新不活跃计时器;
  • 定时告警(scheduled alerts)与仪表盘订阅(dashboard subscriptions)是服务端任务,不会重置用户的不活跃计时器——它们本质上与用户是否在线无关。

从实现上看,src/metabase/server/middleware/session.clj 的maybe-update-session-activity!会更新会话的last_active_at字段,并做了节流(throttle)处理以避免每个请求都触发数据库写入。清理任务删除空闲会话时,使用的是COALESCE(last_active_at, created_at)——即优先以最后活跃时间、缺失时回退到创建时间来判断空闲时长(见 src/metabase/session/db.clj)。

提示:仅当启用了会话超时(即MB_SESSION_TIMEOUT已配置)时,活跃度跟踪才会被激活。

MAX_SESSION_AGEMB_SESSION_TIMEOUT如何协同

当两者同时配置时,会话在"先到达"的那个限制处结束——无论用户是否活跃,绝对年龄上限都会在MAX_SESSION_AGE分钟后来临;而如果用户在达到年龄上限之前就长时间不活跃,则会先被MB_SESSION_TIMEOUT登出。

维度MAX_SESSION_AGEMB_SESSION_TIMEOUT
计时起点登录时刻最后一次活跃时刻
默认值20160 分钟(14 天)未配置(无限期)
配置位置仅环境变量管理界面或环境变量
授权要求所有版本付费版(EE)特性
适用场景定期强制重新认证共享工作站、遗忘的打开标签页

正是由于这种互补性,MB_SESSION_TIMEOUT特别适合共享工作站、容易遗留的打开标签页,以及任何"长时间闲置会话构成安全隐患"的场景:即使不活跃超时窗口内用户一直开着浏览器,MAX_SESSION_AGE也始终是兜底的绝对上限。

强制所有人使用会话 Cookie:MB_SESSION_COOKIES

行为差异

默认情况下,登录页的Remember me复选框是勾选状态,因此会话使用持久 Cookie,可以跨浏览器关闭与重启存活;取消勾选后,关闭浏览器即结束会话。

MB_SESSION_COOKIES=true会改变这一默认行为:

# 强制使用会话 Cookie:关闭浏览器即登出,且移除登录页的 Remember me 复选框 MB_SESSION_COOKIES=true java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar

设置后:

  • 登录页的Remember me复选框会被移除;
  • 所有用户统一采用会话 Cookie(session cookie),浏览器关闭即登出;
  • MAX_SESSION_AGEMB_SESSION_TIMEOUT仍然生效——从不关闭浏览器的用户同样可能被年龄上限或不活跃窗口登出。

底层实现

在 src/metabase/session/settings.clj 中,session-cookies设置默认值为false,其文档注释明确指出:"用户登录会话总会按MAX_SESSION_AGE(默认 2 周)定义的时长过期。这会覆盖登录时的 Remember me 复选框。"

Cookie 是否持久化的判断逻辑位于 src/metabase/request/cookies.clj 的use-permanent-cookies?函数:

  1. MB_SESSION_COOKIES已设置,一律禁用持久 Cookie(返回false);
  2. 否则回退到登录请求体中的remember字段,即用户是否勾选了 Remember me。

结合 src/metabase/request/cookies.clj 的set-session-cookies可以看到:只有当启用持久 Cookie 时,响应才会附带Max-Age指令;没有Max-AgeExpires的 Cookie 属于会话 Cookie,浏览器关闭即被删除。同时,正常会话 Cookie 会附加HttpOnlySameSite(默认lax)等属性,HTTPS 请求下还会附加Secure标志。

浏览器"会话恢复"的例外

需要留意:许多浏览器支持**会话恢复(session restore)**功能——启动时自动重新打开上次的标签页。当会话恢复处于启用状态时,浏览器表现得像从未关闭过一样,会话 Cookie 会跨浏览器重启持续存在。这一点通常可以在浏览器设置中配置,因此MB_SESSION_COOKIES=true的实际效果取决于终端用户的浏览器行为,无法被服务端完全强制。

三个配置的完整对照

配置项作用类型/单位默认值配置位置版本要求
MAX_SESSION_AGE绝对会话寿命上限整数(分钟)20160(14 天)仅环境变量所有版本
MB_SESSION_TIMEOUT不活跃超时登出JSON,单位支持 seconds/minutes/hours未配置(不启用)管理界面(仅分钟/小时)或环境变量(含秒)付费版(EE)
MB_SESSION_COOKIES强制使用会话 Cookie,关闭浏览器即登出布尔值false环境变量所有版本

配置建议与验证方式

什么时候用哪种?可以参考以下思路:

  • 合规驱动的固定周期重新认证(如每 24 小时)→MAX_SESSION_AGE
  • 安全敏感的共享设备、无人值守终端 →MB_SESSION_TIMEOUT(配合MAX_SESSION_AGE兜底);
  • 公共电脑或访客场景,希望"关掉浏览器就登出"→MB_SESSION_COOKIES=true

如何验证配置生效?配置完成后,可观察以下可验证信号:

  • 会话 Cookie 的Max-Agemetabase.TIMEOUTCookie 的Expires值(见 src/metabase/request/cookies.clj 的set-session-timeout-cookie,该 Cookie 在每次请求时按请求时间重新计算过期时刻);
  • Metabase 日志中 SessionCleanup 任务的执行记录,以及应用数据库core_session表中被清理的行数;
  • 接口层可通过管理后台 API(PUT /api/setting/session-timeout)设置超时,非法值(如负数、超 100 年)会返回 HTTP 400,对应的校验测试覆盖在 test/metabase/request/settings_test.clj。

综上,会话过期配置的核心要点可以概括为:MAX_SESSION_AGE划定会话的绝对寿命,MB_SESSION_TIMEOUT治理不活跃会话,MB_SESSION_COOKIES约束关闭浏览器这一动作——三者各司其职又彼此兜底,构成了 Metabase 完整的会话生命周期管理方案。

【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询