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;

Leave a Reply