Embed SDK 简介

Looker 的 Embed SDK 是一个库,您可以将这些函数添加到基于浏览器的 Web 应用的代码中,以便管理您的 Web 应用中的嵌入式信息中心、Looks 和 Discover。嵌入 SDK 可以通过以下方式促进嵌入:

  • 提供封装内容的封装,而无需手动创建 HTML 元素。
  • 提供点对点通信,避免跨帧通信。嵌入 SDK 利用专用的消息通道,处理在您的托管网页和嵌入式 Looker 内容之间传递的跨网域消息。

如果不使用 Embed SDK,您可以使用 dashboard:run:startpage:changed 等 JavaScript 事件(如嵌入式 JavaScript 事件文档页面中所述)调用或响应嵌入式 Looker 内容中的事件。使用 JavaScript 事件嵌入 Looker 内容的开发者必须创建 HTML 元素,以存储嵌入的内容并依靠窗口广播事件在 Web 应用与嵌入内容之间进行通信。

请注意,Looker Embed SDK 与 Looker API 和 Looker API SDK 不同:

  • Looker Embed SDK 位于 Web 应用的客户端代码中,并管理 Looker 嵌入上下文和内容。(Embed SDK 不提供对 Looker API 的访问权限)。
  • Looker API 与 Looker 实例一起位于服务器上,并在 Looker 服务器上执行命令。
  • Looker API 客户端 SDK 位于非浏览器应用的代码中,以便轻松访问 Looker API 函数。

请注意,Looker 无法控制浏览器向 Web 应用发送事件的顺序。这意味着,各浏览器或平台上的事件顺序无法保证。请务必适当编写 JavaScript,以考虑不同浏览器的事件处理方式。

快速示例

此示例会构造 Looker 嵌入上下文,将其插入 ID 为 dashboard 的 DOM 元素,然后在 Looker 嵌入上下文中显示 ID 为 11 的信息中心。dashboard:run:startdashboard:run:complete 事件用于更新嵌入窗口界面的状态,并且编写一个 ID 为 run 的按钮,脚本用于向信息中心发送 dashboard:run 消息。

LookerEmbedSDK.init('looker.example.com', '/auth')

const setupDashboard = (dashboard) => {
  document.querySelector('#run').addEventListener('click', () => {
    dashboard.send('dashboard:run')
  })
}

LookerEmbedSDK.createDashboardWithId(11)
  .appendTo('#dashboard')
  .on('dashboard:run:start',
      () => updateState('#dashboard-state', 'Running')
  )
  .on('dashboard:run:complete',
      () => updateState('#dashboard-state', 'Done')
  )
  .build()
  .connect()
  .then(setupDashboard)
  .catch((error: Error) => {
    console.error('An unexpected error occurred', error)
  })

如需查看更完整的示例,请参阅 Embed SDK 演示文档页面。

设置 Looker Embed SDK

Looker Embed SDK 使用流畅的界面模式。安装 Embed SDK 后,您可以构建嵌入内容连接到嵌入内容

安装 Embed SDK

您可以通过节点软件包管理器 (NPM)(网址为 https://www.npmjs.com/package/@looker/embed-sdk)获取 Looker 的 Embed SDK 库。不过,如果您想查看示例代码或演示,则应改用 Looker Embed SDK 代码库。

如需使用 Looker Embed SDK 代码库安装 Looker Embed SDK,请执行以下操作:

  1. 安装 Node.js(如果尚未安装)。
  2. 下载或克隆 /looker-open-source/embed-sdk 代码库。
  3. 在终端窗口中,导航到 /embed-sdk 目录并运行以下命令:
npm install
npm start

构建嵌入内容

首先,使用您的网络服务器地址以及(可选)服务器上将执行身份验证的端点初始化 SDK。这些内容供所有嵌入内容使用。

如果需要将前缀从浏览器客户端连接到 Looker 服务器,请添加端口号。例如:looker.example.com:443

LookerEmbedSDK.init('looker.example.com', '/auth')

然后,系统会使用一系列步骤构建嵌入内容,以定义其参数。其中一些参数是可选的,有些则是必需的。

首先,使用信息中心 id 或引用信息中心的 url(由单点登录 (SSO) 嵌入文档页面中所述流程创建)创建构建器。

LookerEmbedSDK.createDashboardWithId(id)

LookerEmbedSDK.createDashboardWithUrl(url)

然后,您可以向该构建器添加其他属性,以完成设置。例如,您可以指定在网页的什么位置插入 Looker 嵌入界面。以下调用会将 Looker 嵌入界面放置到 ID 值为 dashboard 的 HTML 元素中:

.appendTo('#dashboard')

您可以添加事件处理脚本:

.on('dashboard:run:start',
  () => updateState('#dashboard-state', 'Running')
)
.on('dashboard:run:complete',
  () => updateState('#dashboard-state', 'Done')
)

最后,构建嵌入元素:

.build()

连接到嵌入的内容

如果您想要向嵌入式元素发送消息以及接收来自嵌入式元素的消息,则需要调用 connect(),它会返回解析为给定元素的通信接口的 promise:

.connect()
.then(setupDashboard)
.catch(console.error)

为 SDK 构建网址

Looker SSO 嵌入网址的主要文档位于单点登录 (SSO) 嵌入文档页面上。为 SDK 创建网址时的唯一区别是,您需要在嵌入网址中添加 sdk=2 参数以及其他参数(如过滤器和 embed_domain 参数)。此参数可让 Looker 确定相应 SDK 是否存在,并充分利用该 SDK 提供的其他功能。例如:

/embed/looks/4?embed_domain=https://mywebsite.com&sdk=2
                                                 ^^^^^^

SDK 无法自行添加此参数,因为它是已签名的 SSO 网址的一部分。

Auth 端点

由于嵌入密钥需要小心保护,因此无法在浏览器中创建嵌入单点登录网址。为了让此过程更简单、更安全,您可以执行以下操作:

  1. 在网络服务器中实现网址签名功能。服务器应该使用 Looker Embed SSO 示例 GitHub 代码库中所述的某个流程返回签名网址。
  2. 将嵌入 SSO 网址传递给 Embed SDK 中的相应签名端点。端点的位置由 LookerEmbedSDK.init() 中的 authUrl 参数指定。

如果指定,则每次仅使用 ID 创建嵌入元素时,系统都会使用该元素的类型、提供的 Looker 主机以及提供的任何参数生成其嵌入网址。例如:

LookerEmbedSDK.init('looker.example.com', '/looker_auth')
LookerEmbedSDK.createcreateDashboardWithId(11)
  .build()

这将调用 /looker_auth 端点,并返回可用于创建嵌入内容的已签名单点登录网址:

src=https://looker.example.com/embed/dashboards/11?sdk=2&embed_host=https://yourhost.example.com

高级身份验证配置

Auth 端点可以进一步配置,以允许自定义请求标头和 CORS 支持。为此,您可以将一个选项对象传递给 init 方法:


LookerEmbedSDK.init('looker.example.com',
  {
    url: 'https://api.acme.com/looker/auth',
    headers: [{'name': 'Foo Header', 'value': 'Foo'}],
    params: [{'name': 'foo', 'value': 'bar'}],
    withCredentials: true // Needed for CORS requests to Auth endpoint include Http Only cookie headers
  })

节点帮助程序

server_utils/auth_utils.ts 中提供了一个签名辅助方法 createSignedUrl()。其用法如下:

import { createSignedUrl } from './auth_utils'

app.get('/looker_auth', function(req, res) {
  // TO DO: Add your code here to authenticate that the request is from a valid user
  const src = req.query.src;
  const host = 'https://looker.example.com'
  const secret = YOUR_EMBED_SECRET
  const user = authenticatedUser
  const url = createSignedUrl(src, user, host, secret);
  res.json({ url });
});

用户数据结构如下:

interface LookerEmbedUser {
  external_user_id: string
  first_name?: string
  last_name?: string
  session_length: number
  force_logout_login?: boolean,
  permissions: LookerUserPermission[]
  models: string[]
  group_ids?: number[]
  external_group_id?: string
  user_attributes?: {[key: string]: any}
  access_filters: {}
}

从 Looker 3.10 中移除了 access_filters 参数,但嵌入网址仍要求提供空白占位符。

问题排查

日志记录

Embed SDK 是基于 chatty 构建的。Chatty 使用调试功能进行日志记录。您可以使用以下命令在浏览器控制台中启用日志记录:

localStorage.debug = 'looker:chatty:*'
```none

Note that both the parent window and the embedded content have separate local storage, so you can enable logging on one, the other, or both. You can disable logging with this command:

```javascript
localStorage.debug = ''