交互式嵌入快速入门

您将在您的应用中嵌入完整的 Metabase 应用程序。登录后,用户可以在您的 Web 应用程序中查看 Metabase 仪表板,并能够使用完整的 Metabase 应用程序来探索他们的数据,并且只能访问他们的数据。

先决条件

  • 您有一个可以嵌入 Metabase 的应用程序。
  • 您拥有 Metabase 的 Pro 或 Enterprise 订阅。如果您不确定从哪里开始,请注册 Pro On-Prem 的免费试用版。如果您安装了 Docker Desktop,您可以直接搜索“metabase-enterprise”来查找 Docker 镜像并运行它。或者,您可以按照这些说明进行操作。

本指南中 featured 的代码可以在我们的 示例 repo 中找到。

在 Metabase 中设置 SSO 和交互式嵌入

在 Metabase 中创建仪表盘

您首先需要创建一些要嵌入的内容。在左侧导航栏中,转到浏览 > 数据库 > 示例数据库。将鼠标悬停在 Invoices 表格上,然后点击闪电图标以 X 射线该表格。Metabase 将创建许多您可以保存为仪表盘的问题。点击按钮将此项另存为仪表盘。Metabase 会将此仪表盘保存在名为“自动生成的仪表盘”的集合中。

访问“自动生成的仪表盘”集合中的仪表盘,并记下其 URL。如果该仪表盘是您创建的第一个仪表盘,则它可能是 /dashboard/1,后跟描述,例如 /dashboard/1-a-look-at-your-invoices-table。您需要在您的应用程序中放入此相对 URL,因为您将使用该仪表盘作为已登录用户访问您应用程序中分析部分时看到的第一个页面。仅包含 ID 并省略 URL 的其余部分就足够了,例如 /dashboard/1

您也可以使用仪表盘的实体 ID。访问“自动生成的仪表盘”集合中的仪表盘。点击信息按钮。在概览中,查找仪表盘的实体 ID。复制该实体 ID。您将在 iframe 的 src URL 中使用该实体 ID:(例如,src=/dashboard/entity/[实体 ID])。

启用交互式嵌入

在 Metabase 中,点击右上角的齿轮图标,然后转到管理设置 > 设置 > 嵌入,然后点击启用按钮。

点击交互式嵌入卡片。在授权来源下,添加您要嵌入 Metabase 的网站或 Web 应用程序的 URL。如果您在本地运行您的应用程序,您可以添加 localhost 并指定端口号,例如 https://127.0.0.1:8080

在您的 Metabase 中使用 JWT 设置 SSO

SameSite 配置

如果您要将 Metabase 嵌入到不同的域名中,您可能需要将会话 Cookie 的 SameSite 值设置为 none

启用使用 JWT 的身份验证

在管理面板的设置部分中,点击身份验证

在标有 JWT 的卡片上,点击设置按钮(您可能需要向下滚动才能查看 JWT 卡片)。

Admin settings: Authentication > JTW setup.

设置 JWT 身份提供商 URI

在您的应用程序中,您将在 /sso/metabase 创建一个 SSO 路由。在 JWT 身份提供商 URI 字段中,输入您的 SSO 路由的 URL。例如,我们的示例应用程序在端口 8080 上运行,因此在这种情况下,此 JWT 身份提供商 URI 可以是 https://127.0.0.1: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";

签名密钥最好设置为环境变量,以避免意外地将您的密钥提交到您的应用程序的 repo。

向您的应用程序服务器添加 JWT 库

向您的应用程序添加 JWT 库。例如,如果您使用的是带有 JavaScript 的 Node 后端,我们建议使用 jsonwebtoken

在您的终端中

npm install jsonwebtoken --save

并在您的应用程序中,require 该库

const jwt = require("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_SITE_URL);
  ssoUrl.searchParams.set("jwt", signUserToken(req.session.user));
  ssoUrl.searchParams.set("return_to", req.query.return_to ?? "/");

  res.redirect(ssoUrl);
});

如果用户之前从未登录过 Metabase,Metabase 将为他们创建一个帐户。

检查点:使用 SSO 登录到您的 Metabase

确保您已退出 Metabase。从 Metabase 登录页面,点击“使用 SSO 登录”。您应该被重定向到您的应用程序。

登录到您的应用程序。您的应用程序应将您重定向到您的 Metabase 欢迎页面。如果该用户还没有 Metabase 账户,Metabase 应该为他们创建一个账户。

在您的应用程序中嵌入 Metabase

现在将您的 Metabase 嵌入到您的应用程序中。您需要设置一个路由来服务于您的嵌入式分析。我们称之为 /analytics。请注意,我们正在使用 restrict 辅助函数(在上面定义),因为只有在用户登录到您的应用程序后才能查看此页面。

在此路由中,我们需要渲染一个 iframe,它将加载您的 Metabase。src 属性 iframe 应该指向您的应用程序的 SSO 端点的相对路径。一旦用户登录到您的应用程序(因此也登录到您的 Metabase),我们添加查询字符串参数 return_to,以便 iframe 显示请求的仪表盘。

METABASE_DASHBOARD_PATH 应该指向您在本指南开头创建的仪表盘的相对路径(/dashboard/[ID],或者如果您使用了仪表盘的实体 ID:/dashboard/entity/[实体 ID])。

app.get("/analytics", restrict, function (req, res) {
  const METABASE_DASHBOARD_PATH = "/dashboard/entity/[Entity ID]"; // e.g., `/dashboard/1` or `/dashboard/entity/nXg0q7VOZJp5a3_hceMRk`
  var 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 负载的 groups 数组中包含的字符串。然后,您可以将该群组名称与我们之前创建的 Metabase 群组“Customer Acme”关联起来。

Mapping user attributes to groups.

务必保存更改

检查点:验证 Metabase 在用户登录时是否将用户分配到群组

首先,退出 Metabase,然后使用 SSO 登录。

然后退出并以管理员身份登录到您的 Metabase,然后转到管理设置 > 人员部分,并验证 Metabase 是否将用户添加到相应的群组。

注意:只有 Metabase 管理员和群组管理员才知道群组。基本用户没有群组的概念,也无法知道他们是哪些群组的成员。

设置权限

现在将权限应用于该群组,以便用户只能看到特定于其帐户的数据。

重置所有用户群组的权限

Metabase 附带两个初始群组:“管理员”和“所有用户”。默认情况下,Metabase 授予“所有用户”群组对连接数据源的访问权限。并且由于 Metabase 授予用户他们最宽松的群组的权限,因此您需要在将“所有用户”群组添加到对数据源和集合的访问权限有限或没有访问权限的群组之前,限制“所有用户”群组可以看到的内容。

要重置所有用户群组的权限,请点击齿轮图标,然后转到管理设置 > 权限。在数据选项卡下,转到群组并选择所有用户。对于查看数据列中的示例数据库,选择“阻止”。点击保存更改,将弹出一个模式窗口,总结您正在更改的内容。点击

Resetting permissions of the All Users group to

允许查看自动生成的仪表盘集合的访问权限

仍在权限选项卡中,点击集合子选项卡,然后点击自动生成的仪表盘集合,并将所有用户群组的集合访问权限设置为查看

点击保存更改,然后点击

将用户属性添加到令牌

您可以将用户属性包含在 JSON Web 令牌中。Metabase 将从 JWT 负载中提取任何键,并将它们存储为用户属性。在其他用例中,您可以使用这些用户属性来设置表的行级权限,以便人们只能看到与其帐户相关联的结果。

如果您正在使用我们的示例应用程序,请编辑用于创建 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 将对应于示例数据库的 Invoices 表中的 Account ID 列。我们将使用此 account_id 用户属性来沙盒化 Invoices 表,以便人们只能看到该表中包含其帐户 ID 的行。

请注意,要在 Metabase 中持久保存用户属性,您需要登录。以非管理员身份登录您的应用程序,并访问包含嵌入式 Metabase 的页面。

使用数据沙盒设置行级权限

在 Metabase 中,转到管理设置 > 权限。在左侧的数据选项卡下,单击一个组。对于“示例数据库”,将其数据访问列更改为精细

Metabase 将显示数据库中表的列表。接下来,将“Invoices”表的数据访问更改为沙盒化

Sandboxing a table.

接下来,Metabase 将弹出一个模态框,提示您将该表中的列与用户属性关联。

保持选中按表中的列筛选选项,并将 Invoices 表中的“Account ID”列与用户属性 account_id 关联。(请注意,仅当用户之前通过 SSO 登录时,Metabase 才会显示用户属性。)

Mapping a column in the sandboxed table to a user attribute.

单击保存以确认您的选择。然后单击右上角的保存更改按钮。

Metabase 将询问您是否确定要执行此操作。您是确定的。

检查点:查看沙盒化仪表板

确保您已退出之前的会话。

登录到您的应用程序,导航到 /analytics。仪表板现在将呈现不同的信息,因为只有数据的子集对这个人可见。单击左侧导航栏底部的浏览数据。查看您的沙盒化 Invoices 表,您应该只看到该表中与该人员帐户关联的行。

隐藏 Metabase 元素

您可以决定显示或隐藏各种 Metabase 元素,例如是否显示导航栏、搜索或 +New 按钮等。

例如,要隐藏嵌入式 Metabase 的徽标和顶部导航栏,您需要将查询字符串参数 ?logo=false&top_nav=false 附加到您包含在 SSO 重定向中的 return_to URL。

在您的 /sso/metabase 路径的处理程序中,添加查询参数

ssoUrl.searchParams.set(
  "return_to",
  `${req.query.return_to ?? "/"}?logo=false&top_nav=false`,
);

检查点:验证隐藏的 UI 元素

注销并重新登录到您的应用程序,然后导航到 /analytics。您的嵌入式 Metabase 应该不包含徽标或顶部导航栏。

下一步

您可以自定义 Metabase 在您的应用程序中的外观:字体、颜色和徽标。

阅读其他版本的 Metabase 的文档。