Apache Superset Embedded SDK 实战:利用 Guest Token 将仪表盘安全嵌入自有应用
2026/9/18 10:51:44 网站建设 项目流程

Apache Superset Embedded SDK 实战:利用 Guest Token 将仪表盘安全嵌入自有应用

【免费下载链接】supersetApache Superset is a Data Visualization and Data Exploration Platform项目地址: https://gitcode.com/gh_mirrors/supers/superset

本文围绕 Apache Superset 仓库中的 superset-embedded-sdk/README.md 展开,讲解如何借助官方 Embedded SDK,通过 iframe 将 Superset 仪表盘嵌入你自己的 Web 应用,并使用 Guest Token 复用宿主应用自身的认证体系,让用户无需登录 Superset 即可查看受控数据。读完本文,你将掌握 SDK 的安装与调用、Guest Token 的签发原理、iframe 沙箱加固方式,以及 SDK 底层的通信与令牌自动刷新机制。

SDK 是什么:一句话理解嵌入原理

Embedded SDK 的核心思路非常简单:在宿主页面中动态创建一个 iframe,让 iframe 加载 Superset 内部的仪表盘页面,从而把仪表盘“镶”进你自己的应用。SDK 负责三件关键事情:

  1. 根据传入的配置构造正确的嵌入式仪表盘 URL({supersetDomain}/embedded/{dashboardId});
  2. 把宿主后端签发的 Guest Token 通过消息通道传递给 iframe 内的 Superset 页面,完成免登录授权;
  3. 提供卸载、获取滚动尺寸、获取永久链接等控制能力,方便宿主应用与嵌入式仪表盘交互。

其核心实现位于 superset-embedded-sdk/src/index.ts 中的embedDashboard函数,源码与本文后续内容一一对应。

快速开始:安装与最小调用

通过 npm 安装

SDK 以 npm 包形式发布,包名为@superset-ui/embedded-sdk

npm install --save @superset-ui/embedded-sdk

安装后在代码中引入并调用:

import { embedDashboard } from "@superset-ui/embedded-sdk"; embedDashboard({ id: "abc123", // 由 Superset 的嵌入配置界面提供 supersetDomain: "https://superset.example.com", mountPoint: document.getElementById("my-superset-container"), // 任意可容纳 iframe 的 HTML 元素 fetchGuestToken: () => fetchGuestTokenFromBackend(), dashboardUiConfig: { // 仪表盘 UI 配置:hideTitle、hideTab、hideChartControls、filters.visible、filters.expanded(可选)、urlParams(可选) hideTitle: true, filters: { expanded: true, }, urlParams: { foo: 'value1', bar: 'value2', // ... } }, // 可选:额外的 iframe sandbox 属性 iframeSandboxExtras: ['allow-top-navigation', 'allow-popups-to-escape-sandbox'] });

通过 CDN 加载

也可以不经过构建工具,直接从 CDN 加载。此时 SDK 会以全局变量supersetEmbeddedSdk暴露:

<script src="https://unpkg.com/@superset-ui/embedded-sdk"></script> <script> supersetEmbeddedSdk.embedDashboard({ // ... 这里填入与上面示例完全相同的参数 }); </script>

说明:SDK 当前仓库版本为0.1.0-alpha.12(见 superset-embedded-sdk/package.json),运行时依赖@superset-ui/switchboard(iframe 消息通信)与jwt-decode(解析 Guest Token 过期时间)。

embedDashboard 参数全解

embedDashboard是 SDK 唯一的入口函数,其类型定义EmbedDashboardParams位于 superset-embedded-sdk/src/index.ts,各参数含义如下:

参数类型必填说明
idstring仪表盘的嵌入配置 ID,由 Superset 的嵌入配置界面生成
supersetDomainstringSuperset 实例域名,需带协议,如https://superset.example.com
mountPointHTMLElement用于挂载 iframe 的宿主页面 HTML 元素
fetchGuestToken() => Promise<string>从宿主后端获取 Guest Token 的函数
dashboardUiConfigUiConfigType仪表盘 UI 与行为配置(见下)
debugboolean是否输出调试日志,默认false
iframeTitlestringiframe 的title属性,默认"Embedded Dashboard"
iframeSandboxExtrasstring[]额外的 iframe sandbox 属性,默认[]

dashboardUiConfig 详解

dashboardUiConfig(类型为UiConfigType,见 src/index.ts)控制嵌入后仪表盘的外观与交互:

字段类型说明
hideTitleboolean隐藏仪表盘标题
hideTabboolean隐藏 Tab 页签
hideChartControlsboolean隐藏图表控制(编辑类控件)
filters.visibleboolean是否显示筛选器面板
filters.expandedboolean筛选器面板是否默认展开
urlParamsRecord<string, any>追加到嵌入式页面 URL 上的自定义查询参数

从源码(src/index.ts)可以看到这些配置最终被序列化为 URL 查询参数传给 iframe:

  • hideTitlehideTabhideChartControls通过位掩码合并为一个数字uiConfighideTitle记 1、hideTab记 2、hideChartControls记 8(源码 src/index.ts);
  • filters.visiblefilters.expanded分别映射为 URL 参数show_filtersexpand_filters,映射表定义在 superset-embedded-sdk/src/const.ts;
  • urlParams中的键与上述参数冲突,urlParams优先生效(见 src/index.ts 的合并顺序)。

认证与授权:Guest Token 机制

嵌入式资源使用一种特殊令牌 ——Guest Token(访客令牌)—— 来授予用户访问 Superset 的权限,而无需你的用户直接登录 Superset。整体流程为:宿主后端向 Superset 的POST /security/guest_token端点申请令牌,再把令牌传给宿主前端;前端 SDK 拿到令牌后用它完成仪表盘嵌入。

在宿主后端创建 Guest Token

宿主后端需要以 HTTPPOST方式请求/security/guest_token,请求体描述该令牌将被授予哪些资源访问权限。Guest Token 还可以携带Row Level Security(行级安全,RLS)规则,按用户动态过滤数据。

发起该请求的代理必须拥有can_grant_guest_token权限。服务端校验逻辑可在 superset/security/api.py 中查看:请求体先经GuestTokenCreateSchema校验,再校验资源存在性,最后调用create_guest_access_token生成令牌。

示例请求体:

{ "user": { "username": "stan_lee", "first_name": "Stan", "last_name": "Lee" }, "resources": [{ "type": "dashboard", "id": "abc123" }], "rls": [ { "clause": "publisher = 'Nintendo'" } ] }

字段说明(与 superset/security/api.py 中的 schema 一一对应):

  • user(可选):用户属性,可用于图表内的 Jinja 模板,便于做个性化渲染;对应UserSchema中的usernamefirst_namelast_name字段;
  • resources(必填):令牌可访问的资源列表,type目前支持dashboard(枚举定义见 superset/security/guest_token.py),id为资源标识;
  • rls(必填):行级安全规则列表,clause为过滤条件,可选dataset指定数据集编号。

令牌生效后的角色与默认配置

在宿主应用内使用 Guest Token 时,Superset 会创建一个匿名用户对象(Anonymous user)来完成认证。该访客匿名用户默认归属于公共角色,对应配置项:

GUEST_ROLE_NAME = "Public"

该配置位于 superset/config.py。Guest Token 底层是 JWT,相关的服务端配置也在 superset/config.py:

配置项默认值说明
GUEST_TOKEN_JWT_SECRET"test-guest-secret-change-me"JWT 签名密钥,生产环境必须更换
GUEST_TOKEN_JWT_ALGO"HS256"JWT 签名算法
GUEST_TOKEN_JWT_EXP_SECONDS300令牌有效期,默认 5 分钟
GUEST_TOKEN_JWT_AUDIENCENoneJWT 受众声明,可配置为固定字符串或回调函数

启用嵌入式功能的特性开关

嵌入功能默认并未开启。服务端需要打开特性开关EMBEDDED_SUPERSET(默认False,见 superset/config.py)。嵌入式仪表盘的查询接口 superset/embedded/api.py 在before_request钩子中检查该开关,未开启时直接返回 404。

iframe 沙箱:默认安全模型与扩展

Embedded SDK 默认以sandbox(沙箱)模式创建 iframe,对 iframe 内内容的执行施加限制。SDK 默认添加的 sandbox 属性(见 src/index.ts)包括:

  • allow-same-origin:同源策略,postMessage通信所必需;
  • allow-scripts:允许执行脚本;
  • allow-presentation:支持图表全屏展示;
  • allow-downloads:支持将图表下载为图片;
  • allow-forms:允许表单提交;
  • allow-popups:支持将图表导出为 CSV 时打开弹窗。

如需更多能力,通过iframeSandboxExtras追加额外的 sandbox 属性,例如放开顶层导航与弹窗逃逸:

iframeSandboxExtras: ['allow-top-navigation', 'allow-popups-to-escape-sandbox']

源码级剖析:SDK 的底层工作机制

1. 通信通道:MessageChannel + Switchboard

iframe 加载完成后,SDK 会创建一个MessageChannel,把其中一个端口通过postMessage传给 iframe 内的 Superset 页面(消息类型常量__embedded_comms__定义在 src/const.ts),从而建立宿主窗口与 iframe 之间的双向通信,参见 src/index.ts。Switchboard(来自@superset-ui/switchboard包)在此基础上封装出类型安全的消息收发 API,Guest Token 正是通过这条通道发送给 iframe 内的仪表盘页面的。

2. Guest Token 自动刷新

Guest Token 默认有效期只有 5 分钟,因此 SDK 会在令牌临近过期时自动重新调用fetchGuestToken并再次通过消息通道下发新令牌,避免嵌入页面因令牌过期而请求失败。刷新时机的计算逻辑位于 superset-embedded-sdk/src/guestTokenRefresh.ts:

  • REFRESH_TIMING_BUFFER_MS = 5000:提前 5 秒刷新,避免 Superset 请求恰好落在过期瞬间;
  • MIN_REFRESH_WAIT_MS = 10000:最小刷新间隔 10 秒,防止异常场景下高频刷新请求;
  • DEFAULT_TOKEN_EXP_MS = 300000:当解析 JWT 的exp失败时,按 5 分钟兜底计算。

SDK 通过jwt-decode解析 JWT,兼容整数(秒)与 ISO 字符串两种exp格式(见 src/guestTokenRefresh.ts)。对应的单元测试在 superset-embedded-sdk/src/guestTokenRefresh.test.ts,覆盖了 epoch 秒、带小数的 epoch、ISO 日期、过期令牌与非法日期共五种场景。

3. 返回的 EmbeddedDashboard 控制句柄

embedDashboard返回一个 Promise,resolve 出的对象(类型EmbeddedDashboard,见 src/index.ts)提供四个方法:

方法说明
getScrollSize()获取 iframe 内容可滚动尺寸{ width, height },用于自适应宿主页面布局
unmount()mountPoint中移除 iframe,卸载嵌入式仪表盘
getDashboardPermalink(anchor)获取仪表盘指定位置的永久链接
getActiveTabs()获取当前激活的 Tab 列表

这四个方法都是通过 Switchboard 通道向 iframe 内的页面发起远程调用(见 src/index.ts),宿主应用可以据此实现“随仪表盘 Tab 切换而联动自身导航”“提供返回按钮时主动卸载”等产品化交互。

端到端接入清单

将以上内容串成一个完整的接入流程:

  1. 服务端:打开特性开关EMBEDDED_SUPERSET = True,并设置生产环境的GUEST_TOKEN_JWT_SECRET
  2. 权限:为签发令牌的账号授予can_grant_guest_token权限,并按需配置GUEST_ROLE_NAME对应的角色及其可访问资源;
  3. 宿主后端:实现一个受你自身认证体系保护的接口,内部调用POST /security/guest_token构造带userresourcesrls的请求体并返回令牌;
  4. 宿主前端:安装@superset-ui/embedded-sdk,调用embedDashboard,把fetchGuestToken指向第 3 步的接口,并传入idsupersetDomainmountPoint
  5. 交互增强:按需使用dashboardUiConfig定制 UI,用iframeSandboxExtras调整沙箱策略,用返回值中的四个方法实现卸载、滚动自适应、永久链接与 Tab 联动。

总结

Superset Embedded SDK 以“iframe 嵌入 + Guest Token 授权 + 消息通道通信”三件套,提供了一条将 Superset 仪表盘无缝接入自有产品体系的标准路径:用户认证完全复用宿主应用,数据访问通过resources与 RLS 规则精细收敛,令牌自动刷新保证了长时间使用的稳定性,沙箱默认策略则守住安全底线。若需更深入地调试或扩展,建议直接阅读 superset-embedded-sdk/src/index.ts 与 superset/security/api.py 两份核心源码。

【免费下载链接】supersetApache Superset is a Data Visualization and Data Exploration Platform项目地址: https://gitcode.com/gh_mirrors/supers/superset

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询