交互式嵌入快速入门
您将把完整的 Metabase 应用程序嵌入到您的应用中。登录后,人们可以在您的 Web 应用中查看 Metabase 仪表板,并能够使用完整的 Metabase 应用程序来探索他们的数据,且仅限于他们的数据。
先决条件
- 您有一个可以嵌入 Metabase 的应用程序。
- 您拥有 Metabase 的 Pro 或 Enterprise 订阅。如果您不确定从何开始,请注册 Pro 本地版 的免费试用。如果您已安装 Docker Desktop,只需搜索“metabase-enterprise”即可找到 Docker 镜像并运行它。或者,您也可以按照这些说明进行操作。
本指南中介绍的代码可在我们的示例仓库中找到。
在 Metabase 中设置 SSO 和交互式嵌入
准备好要嵌入的仪表板
您首先需要一个要嵌入的仪表板。如果您还没有,可以使用 Metabase 新实例中包含的示例仪表板,或者使用 X 光功能生成一个。
访问该仪表板并记下其 URL,例如 /dashboard/1-e-commerce-insights
。您需要将此相对 URL 放入您的应用程序中,因为您将使用该仪表板作为登录用户访问应用程序中分析部分时看到的第一个页面。只需包含 ID 并省略 URL 的其余部分即可,例如 /dashboard/1
。
您也可以使用仪表板的实体 ID (Entity ID)。在仪表板上,点击 信息 按钮。在 概览 选项卡中,查找仪表板的 实体 ID。复制该实体 ID。您将在 iframe 的 src
URL 中使用该实体 ID(例如,src=/dashboard/entity/[实体 ID]
)。
启用交互式嵌入
在 Metabase 中,点击右上角的 齿轮 图标,然后转到 管理设置 > 设置 > 嵌入。找到 交互式嵌入 并点击 启用 开关。
点击 交互式嵌入 下的 配置 按钮。在 授权来源 下,添加您要嵌入 Metabase 的网站或 Web 应用程序的 URL。如果您在本地运行应用程序,可以添加 localhost 并指定端口号,例如 http://localhost:8080
。
SameSite 配置
如果您将 Metabase 嵌入到不同的域中,您可能需要将会话 cookie 的 SameSite 值设置为 none
在您的 Metabase 中使用 JWT 设置 SSO
启用 JWT 身份验证
仍在管理面板的 设置 部分时,点击 身份验证。
在标有 JWT 的卡片上,点击 设置 按钮(您可能需要向下滚动才能看到 JWT 卡片)。
设置 JWT 身份提供者 URI
在您的应用程序中,您将为 SSO 创建一个路由:/sso/metabase
。在 JWT 身份提供者 URI 字段中,输入您的 SSO 路由的 URL。例如,我们的示例应用程序在端口 8080 上运行,因此在这种情况下,此 JWT 身份提供者 URI 可以是 http://localhost:8080/sso/metabase
。
生成 JWT 签名密钥
点击 生成密钥 按钮以生成一个签名密钥。请务必保密此密钥。您将在您的服务器上使用它。如果您生成另一个密钥,将覆盖现有密钥,因此您也需要在您的应用程序中更新该密钥。
复制此密钥,下一节将需要它。
保存并启用 JWT 身份验证
我们稍后将设置群组同步,但现在,请务必点击 保存并启用 按钮以激活 JWT 身份验证。
在您的应用程序服务器中设置 JWT SSO
将签名密钥和 Metabase 站点 URL 添加到您的应用程序
在这里,您需要输入一些值以使 SSO 正常工作。
您需要在应用程序中声明两个常量
METABASE_JWT_SHARED_SECRET
,将从 Metabase 获取的 JWT 签名密钥粘贴到此处。METABASE_SITE_URL
,指向您的 Metabase 根路径。
const METABASE_JWT_SHARED_SECRET = "YOURSIGNINGKEY";
const METABASE_SITE_URL = "https://your-domain.metabaseapp.com";
签名密钥最好设置为环境变量,以避免意外地将密钥提交到您应用程序的仓库中。
将 JWT 库添加到您的应用程序服务器
将 JWT 库添加到您的应用程序。例如,如果您正在使用 Node.js 后端和 JavaScript,我们推荐使用 jsonwebtoken。
在您的终端中
npm install jsonwebtoken --save
在您的应用程序中,引入该库
import jwt from "jsonwebtoken";
限制对某些路由的访问
您的应用程序应该已经有某种方法确保某些路由在登录后才能访问。我们的示例使用一个名为 restrict
的简单辅助函数来保护这些路由
function restrict(req, res, next) {
if (req.session.user) {
next();
} else {
req.session.returnTo = req.originalUrl;
req.session.error = "Access denied!";
res.redirect("/login");
}
}
添加一个函数来签署用户
我们需要编写一个函数,使用 JWT 库来签署用户 JWT。
const signUserToken = user =>
jwt.sign(
{
email: user.email,
first_name: user.firstName,
last_name: user.lastName,
exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minute expiration
},
METABASE_JWT_SHARED_SECRET,
);
添加 sso/metabase
路由
您需要添加一个路由,以便通过 JWT 使用 SSO 将用户登录到您的 Metabase。如果用户尚未登录您的应用程序,您的应用程序应将其重定向到您的登录流程。在下面的代码中,此检查和重定向由我们之前介绍的 restrict
函数处理。
app.get("/sso/metabase", restrict, (req, res) => {
const ssoUrl = new URL("/auth/sso", METABASE_INSTANCE_URL);
ssoUrl.searchParams.set("jwt", signUserToken(req.session.user));
ssoUrl.searchParams.set("return_to", req.query.return_to?.toString() ?? "/");
res.redirect(ssoUrl.href);
});
如果此人以前从未登录过 Metabase,Metabase 将为其创建一个账户。
检查点:使用 SSO 登录您的 Metabase
请确保您已从 Metabase 中登出。在 Metabase 登录页面,点击“使用 SSO 登录”。您应该会被重定向到您的应用程序。
登录您的应用程序。您的应用程序应该将您重定向到 Metabase 欢迎页面。如果此人还没有 Metabase 账户,Metabase 应该会为他们创建一个账户。
在您的应用程序中嵌入 Metabase
现在,将 Metabase 嵌入到您的应用程序中。您需要设置一个路由来提供嵌入式分析服务。我们将其命名为 /analytics
。请注意,我们使用了 restrict
辅助函数(如上定义),因为此页面只有在用户登录您的应用程序后才能查看。
在此路由中,我们需要渲染一个将加载 Metabase 的 iframe。iframe 的 src
属性应指向您的应用程序 SSO 端点的相对路径。一旦用户登录您的应用程序(并因此登录您的 Metabase),我们将添加查询字符串参数 return_to
,以便 iframe 显示请求的仪表板。
METABASE_DASHBOARD_PATH
应该指向您在本指南开头创建的仪表板的相对路径(/dashboard/[ID]
,如果您使用了仪表板的实体 ID,则是 /dashboard/entity/[实体 ID]
)。
app.get("/analytics", restrict, (req, res) => {
const METABASE_DASHBOARD_PATH = "/dashboard/entity/[Entity ID]"; // e.g., `/dashboard/1` or `/dashboard/entity/nXg0q7VOZJp5a3_hceMRk`
const iframeUrl = `/sso/metabase?return_to=${METABASE_DASHBOARD_PATH}`;
res.send(
`<iframe src="${iframeUrl}" frameborder="0" width="1280" height="600" allowtransparency></iframe>`,
);
});
METABASE_DASHBOARD_PATH
只是用户登录时看到的第一个内容,但您可以将该路径设置为任何 Metabase URL。由于您嵌入的是完整的 Metabase,用户将能够下钻数据并查看其他问题、仪表板和集合。
检查点:在您的应用程序中查看 Metabase 仪表板
使用您应用程序的用户现在应该能够访问 /analytics
并查看您嵌入的 Metabase 仪表板。
如何测试:登录您的应用程序并访问 /analytics
路由。您应该能看到 Metabase 仪表板。
如果您使用 Safari 浏览器,并且 Metabase 和您的应用程序来自不同的域,您可能需要前往 Safari 设置并关闭阻止跨网站跟踪。
在 Metabase 中设置群组
现在您已经设置了 SSO 和交互式嵌入,是时候设置群组了,这样您就可以将权限应用于您嵌入的 Metabase 实体(问题、仪表板、集合等)。
将 groups
键添加到您的令牌
回想一下用于创建 JWT 的 signUserToken
函数。将 groups
键添加到映射到数组的已签名令牌中。Metabase 将查看该数组中的值,以确定是否有任何值映射到 Metabase 中的群组(我们稍后将逐步介绍群组映射)。
const signUserToken = user =>
jwt.sign(
{
email: user.email,
first_name: user.firstName,
last_name: user.lastName,
groups: ["Customer-Acme"],
exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minute expiration
},
METABASE_JWT_SHARED_SECRET,
);
在 Metabase 中创建群组
在 Metabase 中,点击 齿轮 图标,然后转到 管理设置 > 人员 > 群组。点击 创建群组 按钮。添加一个与您应用程序中的群组对应的群组。如果您正在使用示例应用程序,请添加一个名为 Customer Acme
的群组。
在 Metabase 和您的应用程序之间同步群组
您将把 groups
键中的此字符串映射到 Metabase 群组,以便当用户通过 SSO 登录时,Metabase 会自动将他们分配到相应的 Metabase 群组。
在 Metabase 的管理部分,转到 设置 > 身份验证。滚动到 JWT 卡片并点击 编辑。
在 群组架构 部分,开启 同步群组成员资格。对于您要同步的每个群组,添加一个群组映射。当您点击 新建映射 时,输入“Customer-Acme”,这是您在 JWT payload 的 groups
数组中包含的字符串。然后,您可以将该群组名称与我们之前创建的 Metabase 群组“Customer Acme”关联起来。
请务必 保存更改。
检查点:验证 Metabase 在用户登录时是否将他们分配到群组
首先,从 Metabase 登出并使用 SSO 登录。
然后登出并以管理员身份登录您的 Metabase,转到 管理设置 > 人员 部分,验证 Metabase 是否已将此人添加到相应的群组。
注意:只有 Metabase 管理员和群组管理员知道群组。普通用户没有群组概念,也无法知道他们属于哪个群组。
设置权限
现在,为该群组应用权限,以便用户只能看到其账户的特定数据。
重置“所有用户”群组的权限
Metabase 默认包含两个初始群组:“管理员”和“所有用户”。默认情况下,Metabase 授予“所有用户”群组访问已连接数据源的权限。由于 Metabase 会授予用户其权限最宽松群组的权限,因此在将他们添加到对数据源和集合具有有限或无访问权限的群组之前,您需要限制“所有用户”群组可以看到的内容。
要重置“所有用户”群组的权限,请点击 齿轮 图标,然后转到 管理设置 > 权限。在 数据 选项卡下,转到 群组 并选择 所有用户。对于 查看数据 列中的 示例数据库,选择“已阻止”。点击 保存更改,将弹出一个模式窗口,总结您正在进行的更改。点击 是。
允许查看对自动生成的仪表板集合的访问权限
仍在 权限 选项卡中,点击 集合 子选项卡,然后点击 自动生成的仪表板 集合,并将 所有用户 群组的 集合访问 权限设置为 查看。
点击 保存更改,然后点击 是。
向令牌添加用户属性
您可以在 JSON Web 令牌中包含用户属性。Metabase 将从 JWT payload 中获取任何键,并将其存储为用户属性。除其他用例外,您可以使用这些用户属性来设置表的行级权限,以便用户只能看到与其账户相关联的结果。
如果您使用的是我们的示例应用程序,请编辑用于创建 JWT 的 signUserToken
函数,添加一个键 account_id
,其值为 28
。
const signUserToken = user =>
jwt.sign(
{
email: user.email,
first_name: user.firstName,
last_name: user.lastName,
// hard-coded account ID added to this object
// just to test sandboxing with Metabase's Sample Database: Invoices table
account_id: 28,
groups: ["Customer-Acme"],
exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minute expiration
},
METABASE_JWT_SHARED_SECRET,
);
该用户 ID 将对应于示例数据库的“发票”表中的 Account ID
列。我们将使用此 account_id
用户属性来沙盒化“发票”表,这样用户就只能看到该表中包含其账户 ID 的行。
请注意,要在 Metabase 中保留用户属性,您需要登录。以非管理员身份登录您的应用程序,并访问包含您嵌入的 Metabase 的页面。
使用数据沙盒设置行级权限
在 Metabase 中,转到 管理设置 > 权限。在左侧的 数据 选项卡下,点击一个群组。对于“示例数据库”,将其 数据访问 列更改为 精细。
Metabase 将显示数据库中的表列表。接下来,将“发票”表的 数据访问 更改为 沙盒化。
接下来,Metabase 将弹出一个模式窗口,提示您将该表中的列与用户属性关联起来。
勾选 按表中列筛选 选项,并将发票表中的“账户 ID”列与用户属性 account_id
关联起来。(请注意,Metabase 仅在用户之前通过 SSO 登录过时才会显示用户属性。)
点击 保存 以确认您的选择。然后点击右上角的 保存更改 按钮。
Metabase 将询问您是否确定要执行此操作。您确定。
检查点:查看沙盒化仪表板
请确保您已从之前的会话中登出。
登录您的应用程序,导航到 /analytics
。仪表板现在将呈现不同的信息,因为此人只能看到数据的一个子集。点击左侧导航底部的 浏览数据。查看您的沙盒化 发票 表,您应该只看到该表中与该用户的账户关联的行。
隐藏 Metabase 元素
您可以决定显示或隐藏各种 Metabase 元素,例如是否显示导航栏、搜索或 +新建 按钮等。
例如,要隐藏嵌入式 Metabase 的徽标和顶部导航栏,您需要在 SSO 重定向中包含的 return_to
URL 后附加查询字符串参数 ?logo=false&top_nav=false
。
在您的 /sso/metabase
路径的处理程序中,添加查询参数
ssoUrl.searchParams.set(
"return_to",
`${req.query.return_to ?? "/"}?logo=false&top_nav=false`,
);
检查点:验证隐藏的 UI 元素
再次登出并登录您的应用程序,导航到 /analytics
。您嵌入的 Metabase 应该不再包含徽标或顶部导航。
后续步骤
您可以自定义 Metabase 在您的应用程序中的外观:字体、颜色和徽标。
阅读其他 Metabase 版本 的文档。