嵌入式分析SDK - 认证

⚠️ 此功能处于测试阶段。您可以随意尝试使用它,但请注意,某些内容可能会发生变化(并且可能无法按预期工作)。

嵌入式分析 SDK 仅适用于 专业版企业版 计划(包括自托管和 Metabase Cloud),但您可以通过使用 API 密钥进行身份验证来在本地计算机上使用 SDK 进行测试,而无需许可证。

处理 SDK 时处理身份验证的注意事项。

从您的服务器验证人员

SDK 需要您的应用程序后端中的一个端点,该端点将签署人员并返回一个令牌,SDK 将使用该令牌对 Metabase 的调用进行身份验证。

SDK 将调用此端点以获取新的令牌,或刷新即将到期的现有令牌。

生成令牌的示例代码

此示例在应用程序中设置了一个端点 /sso/metabase,该端点使用共享密钥创建令牌以对 Metabase 的调用进行身份验证。

const express = require("express");
const cors = require("cors");
const session = require("express-session");
const jwt = require("jsonwebtoken");
const fetch = require("node-fetch");

async function metabaseAuthHandler(req, res) {
  const { user } = req.session;

  if (!user) {
    return res.status(401).json({
      status: "error",
      message: "not authenticated",
    });
  }

  const token = jwt.sign(
    {
      email: user.email,
      first_name: user.firstName,
      last_name: user.lastName,
      groups: [user.group],
      exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minutes expiration
    },
    // This is the JWT signing secret in your Metabase JWT authentication setting
    METABASE_JWT_SHARED_SECRET,
  );
  const ssoUrl = `${METABASE_INSTANCE_URL}/auth/sso?token=true&jwt=${token}`;

  try {
    const response = await fetch(ssoUrl, { method: "GET" });
    const token = await response.json();

    return res.status(200).json(token);
  } catch (error) {
    if (error instanceof Error) {
      res.status(401).json({
        status: "error",
        message: "authentication failed",
        error: error.message,
      });
    }
  }
}

const app = express();

// Middleware

// If your FE application is on a different domain from your BE, you need to enable CORS
// by setting Access-Control-Allow-Credentials to true and Access-Control-Allow-Origin
// to your FE application URL.
//
// Limitation: We currently only support setting one origin in Authorized Origins in Metabase for CORS.
app.use(
  cors({
    credentials: true,
  }),
);

app.use(
  session({
    secret: SESSION_SECRET,
    resave: false,
    saveUninitialized: true,
    cookie: { secure: false },
  }),
);
app.use(express.json());

// routes
app.get("/sso/metabase", metabaseAuthHandler);
app.listen(PORT, () => {
  console.log(`API running at https://127.0.0.1:${PORT}`);
});

获取 Metabase 身份验证状态

您可以使用 useMetabaseAuthStatus 钩子查询 Metabase 的身份验证状态。如果您想在用户未进行身份验证时完全隐藏 Metabase 组件,则此操作非常有用。

此钩子只能在由 MetabaseProvider 包装的组件中使用。

const auth = useMetabaseAuthStatus();

if (auth.status === "error") {
  return <div>Failed to authenticate: {auth.error.message}</div>;
}

if (auth.status === "success") {
  return <InteractiveQuestion questionId={110} />;
}

自定义 JWT 身份验证

您可以通过在 config prop 中指定 fetchRefreshToken 函数来自定义 SDK 获取刷新令牌的方式。

/**
 * This is the default implementation used in the SDK.
 * You can customize this function to fit your needs, such as adding headers or excluding cookies.

 * The function must return a JWT token object, or return "null" if the user is not authenticated.

 * @returns {Promise<{id: string, exp: number} | null>}
 */
async function fetchRequestToken(url) {
  const response = await fetch(url, {
    method: "GET",
    credentials: "include",
  });

  return await response.json();
}

// Pass this configuration to MetabaseProvider.
// Wrap the fetchRequestToken function in useCallback if it has dependencies to prevent re-renders.
const config = { fetchRequestToken };

使用 API 密钥本地进行身份验证

嵌入式分析 SDK 仅在生产环境中支持 JWT 身份验证。API 密钥身份验证仅支持本地开发和评估目的。

要尝试 SDK 进行本地开发,您可以使用 API 密钥进行身份验证。

首先,创建一个 API 密钥

然后您可以使用 API 密钥在您的应用程序中对 Metabase 进行身份验证。您只需在配置对象中包含 API 密钥即可,键为:apiKey

const metabaseConfig = {
    ...
    apiKey: "YOUR_API_KEY"
    ...
};

export default function App() {
  return (
    <MetabaseProvider config={metabaseConfig} className="optional-class">
      Hello World!
    </MetabaseProvider>
  );

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

想要改进这些文档吗? 提出更改。