Embedding Superset Dashboard into a Private Website with Authentication and Row-Level Security (RLS)
Apache Superset is a powerful business intelligence tool that allows users to create dashboards and visualize data effectively. In this guide, we will walk through the steps required to embed a Superset dashboard into a private website with authentication and Row-Level Security (RLS).
Prerequisites
Before starting, ensure you have:
- Superset installed and running
- A configured Superset user with embed permissions
- A React frontend or another web framework ready for embedding
Step 1: Enable Embedding in Superset
To embed Superset dashboards, update the Superset configuration file (superset_config.py) with the following settings:
# Enable the embedded Superset feature FEATURE_FLAGS = { “EMBEDDED_SUPERSET”: True } # Enable Cross-Origin Resource Sharing (CORS) ENABLE_CORS = True CORS_OPTIONS = { “supports_credentials”: True, “allow_headers”: “*”, “expose_headers”: “*”, “resources”: “*”, “origins”: [“http://localhost:3000”] # React URL or frontend URL } # Dashboard Embedding Configuration GUEST_ROLE_NAME = “Gamma” GUEST_TOKEN_JWT_SECRET = “PASTE_GENERATED_SECRET_HERE” # Replace with a secure secret GUEST_TOKEN_JWT_ALGO = “HS256” GUEST_TOKEN_HEADER_NAME = “X-GuestToken” GUEST_TOKEN_JWT_EXP_SECONDS = 300 # Token expiry time set to 5 minutes |
This configuration enables the embedding feature, sets up CORS, and configures authentication for embedding.
Step 2: Installing Dependencies
In your React project, install the required packages:
# Using npm npm install –save @superset-ui/embedded-sdk axios # OR using Yarn yarn add @superset-ui/embedded-sdk axios |
Step 3: Generate an Authentication Token
To authenticate and fetch the required token for embedding, we will create a function that generates the guest token. This logic should be placed in the backend, not in the frontend, for security reasons.
import axios from “axios”; const supersetUrl = ‘http://YOUR_DASHBOARD_URL_HERE’; // Replace with your Superset URL const supersetApiUrl = `${supersetUrl}/api/v1/security`; const dashboardId = “EMBED_ID_HERE”; // Replace with actual dashboard ID const getToken = async (): Promise<string | null> => { try { // Step 1: Authenticate and get access token const loginBody = { username: “YOUR_USERNAME_WITH_EMBED_N_DASHBOARD_PERMISSION”, // Use a dedicated user with limited permissions password: “YOUR_PASSWORD_WITH_EMBED_N_DASHBOARD_PERMISSION”, provider: “db”, refresh: true, }; const loginResponse = await axios.post(`${supersetApiUrl}/login`, loginBody, { headers: { “Content-Type”: “application/json” }, }); const accessToken = loginResponse.data.access_token; console.log(“Access Token:”, accessToken); // Step 2: Generate guest token for embedding const guestTokenBody = { resources: [{ type: “dashboard”, id: dashboardId }], rls: [], // Configure Row-Level Security if needed user: { username: “report-viewer”, first_name: “report-viewer”, last_name: “report-viewer”, }, }; const guestTokenResponse = await axios.post(`${supersetApiUrl}/guest_token/`, guestTokenBody, { headers: { “Content-Type”: “application/json”, Authorization: `Bearer ${accessToken}`, }, }); return guestTokenResponse.data.token; } catch (error) { console.error(“Error fetching Superset token:”, error); return null; } }; |
Step 4: Embedding the Superset Dashboard in React
Now, use the generated token to embed the Superset dashboard into your React application.
import React, { useEffect } from “react”; import { embedDashboard } from “@superset-ui/embedded-sdk”; import { Divider } from “@mui/material”; import { useTheme, useMediaQuery } from “@mui/material”; import { useSidebar } from “./sidebarcontext”; const AdminDashboard: React.FC = () => { const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down(“sm”)); const { isOpen } = useSidebar(); const supersetUrl = ‘http://YOUR_DASHBOARD_URL_HERE’ // Replace with your Superset URL const dashboardId = “EMBED_ID_HERE”; // Replace with actual dashboard ID useEffect(() => { const embedSupersetDashboard = async () => { const guestToken = await getToken(); if (!guestToken) { console.error(“Failed to retrieve guest token.”); return; } const container = document.getElementById(“superset-container”); if (container) { embedDashboard({ id: dashboardId, supersetDomain: supersetUrl, mountPoint: container, // The HTML element where the dashboard will be embedded fetchGuestToken: async () => guestToken, // Provide the generated token dashboardUiConfig: { hideTitle: true }, // Hide dashboard title }); } else { console.error(“Superset container not found”); } }; embedSupersetDashboard(); }, []); return ( <div> {/* Divider for mobile layout adjustments */} {isMobile && <Divider style={{ marginTop: isOpen ? “0.5rem” : “auto” }} />} {/* Container to embed Superset dashboard */} <div style={{ display: “flex”, marginLeft: “10px”, marginTop: “5px”, backgroundColor: “#f3f3f4”, width: “100%”, height: “100vh” }}> <div id=”superset-container” style={{ width: “100%”, height: “100%” }} /> </div> </div> ); }; export default AdminDashboard; |