嵌入式分析 SDK - 身分驗證
⚠️ 此功能為 Beta 版。歡迎隨意試用,但請注意,內容可能會變更 (而且可能無法如預期般運作)。
嵌入式分析 SDK 僅適用於 Pro 和 Enterprise 方案 (包括自架託管和 Metabase Cloud)。不過,您可以在本機電腦上試用 SDK,而無需授權,方法是使用 API 金鑰驗證您的嵌入。
關於使用 SDK 時處理身分驗證的注意事項。
從您的伺服器驗證人員身分
SDK 需要您應用程式後端的端點,該端點會讓使用者登入您的 Metabase 並傳回權杖。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 session = await response.text();
console.log("Received session", session);
return res.status(200).set("Content-Type", "application/json").end(session);
} 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 帳戶
每位終端使用者必須擁有自己的 Metabase 帳戶。
讓終端使用者共用 Metabase 帳戶的問題在於,即使您透過 SDK 在用戶端篩選資料,所有終端使用者仍然可以存取工作階段權杖,他們可以使用該權杖直接透過 API 存取 Metabase,以取得他們不應看到的資料。
但是,如果每位終端使用者都有自己的 Metabase 帳戶,您可以在 Metabase 中設定權限,而且每個人都只會存取他們應有的資料。
除此之外,我們認為共用帳戶是不公平的使用方式。SDK 的公平使用方式包括讓嵌入式分析的每位終端使用者都擁有自己的 Metabase 帳戶。
取得 Metabase 身分驗證狀態
您可以使用 useMetabaseAuthStatus
Hook 查詢 Metabase 身分驗證狀態。如果您想要在使用者未通過身分驗證時完全隱藏 Metabase 元件,這會很有用。
此 Hook 只能在由 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
屬性中指定 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。您只需要使用金鑰 apiKey
將您的 API 金鑰包含在組態物件中即可。
const authConfig = {
...
apiKey: "YOUR_API_KEY"
...
};
export default function App() {
return (
<MetabaseProvider authConfig={authConfig} className="optional-class">
Hello World!
</MetabaseProvider>
);
閱讀其他 Metabase 版本的文件。