你构建了一个 SaaS 产品,客户希望在产品内部就能看到自己的数据——而不是在另一个工具里、隔着另一次登录。Metabase 通过嵌入(embedding)解决了这个问题,但"嵌入一个仪表盘"背后隐藏着三种截然不同的模式,以及一个决定成败的问题:如何确保每个客户严格地只能看到自己的数据。
为什么要把分析嵌入产品
把客户导向一个独立的工具,会损失上下文、增加登录环节、降低使用率。嵌入式分析——在你自己的界面内、带着你的品牌展示仪表盘——让数据成为产品的一部分:数据出现在决策发生的地方。问题从来不是要不要做,而是怎么做——而在 Metabase 中,"怎么做"有三种形式。
Metabase 的三种嵌入模式
- 静态嵌入(签名)——一个带有服务器端签名 JWT 的 iframe。参数(例如客户标识)被锁定在令牌内部;用户无法交互,也无法修改它们。适合每个客户一个固定面板的场景。开源版本即可使用。
- 交互式嵌入——嵌入完整的 Metabase,通过 SSO(JWT)登录,客户可以自行探索并创建自己的问题。需要 Pro/Enterprise,并可与数据沙箱(data sandboxing)结合使用。
- 嵌入式分析 SDK(React)——将 Metabase 组件嵌入你的应用,对布局和主题进行精细控制。属于 Enterprise 功能。
决定成败的问题:多租户隔离
在多租户产品中,最严重的错误就是让一个客户看到另一个客户的数据。安全隔离取决于所采用的模式:
- 静态嵌入——租户作为锁定参数(locked)放入在你后端签名的 JWT 中。由于令牌使用服务器密钥签名,客户无法伪造出另一个标识。这是开源版本的隔离途径。
- 交互式嵌入 + 数据沙箱——根据 JWT 中的用户自动应用行级过滤,即使用户自由探索也是如此。这是开放式探索场景下最强的隔离方式——属于 Enterprise。
- 无沙箱的 OSS——当你需要在开源版本中进行探索时,途径是按租户以连接/schema 分离数据(与我们关于 Metabase OSS 治理一文中相同的架构)。
绝对不能做的事
- 把
tenant_id放在可编辑的 URL 参数里——客户改一下数字就能看到邻居的数据。 - 不带签名就嵌入(公开嵌入),却以为"没人会猜到这个 URL"。
- 依赖前端来做过滤——过滤必须存在于签名令牌或数据库中,绝不能放在 JavaScript 里。
选择正确的模式
实用原则:如果客户只需要查看每个租户一个面板,签名静态嵌入就能解决——而且在开源版本上即可运行。如果客户需要探索并创建带行级隔离的问题,那就是交互式嵌入 + 数据沙箱(Enterprise)。如果需要探索但预算限于 OSS,就在架构层面按租户分离数据。真正的错误是被演示的光鲜所吸引来做选择,而不是根据实际的隔离需求。
常见问题
在 Metabase 开源版本中能实现安全的多租户嵌入吗?
可以,针对每个客户的固定面板:静态嵌入使用在你服务器上签名的 JWT,将租户标识作为参数锁定。客户无法伪造出另一个。若需要带自动行级隔离的开放式探索,那就需要 Pro/Enterprise 的数据沙箱——或者在开源版本中按租户以连接/schema 分离数据。
客户能否绕过过滤,看到其他租户的数据?
不能,只要租户标识作为锁定参数放在签名令牌内部(或通过数据沙箱应用)。由于签名是使用服务器密钥完成的,篡改令牌就会使嵌入失效。只有当过滤通过可编辑的 URL 传递,或仅在前端应用时,才会发生泄露——而这正是正确架构所要避免的。