嵌入 SDK 简介

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

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

如果没有 Embed SDK,您可以使用 dashboard:run:startpage:changed 等 JavaScript 事件来调用或响应嵌入式 Looker 内容中的事件,详见嵌入式 JavaScript 事件文档页面。使用 JavaScript 事件嵌入 Looker 内容的开发者必须创建 HTML 元素来容纳嵌入的内容,并依赖于窗口广播事件来实现 Web 应用与嵌入内容之间的通信。

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

  • Looker 嵌入 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 嵌入 SDK

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

安装 Embed SDK

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

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

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

构建嵌入内容

首先,使用 Web 服务器的地址初始化该 SDK,并根据需要使用服务器上将执行身份验证的端点来初始化。所有嵌入内容都会使用这些标记。

如果需要通过浏览器客户端访问 Looker 服务器,请添加端口号。例如:looker.example.com:443

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

然后,通过一系列步骤构建嵌入内容来定义其参数。其中一些参数是可选的,有些则是必需的。

该流程首先使用信息中心 id 或引用信息中心的 url(由签名嵌入文档页面中所述的流程创建)创建构建器。

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 已签名嵌入网址的主要文档位于已签名嵌入文档页面上。为 SDK 创建网址时,唯一的区别在于,您需要将 sdk=2 参数添加到嵌入网址中,以及其他参数(例如过滤条件和 embed_domain 参数)。借助此参数,Looker 可以确定是否存在该 SDK,并利用该 SDK 提供的其他功能。例如:

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

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

身份验证端点

由于需要小心保护嵌入密钥,因此无法在浏览器中创建已签名的嵌入网址。为了简化流程并提高安全性,您可以改为按以下步骤操作:

  1. 在您的 Web 服务器中实现网址签名函数。服务器应使用 Looker 嵌入 SSO 示例 GitHub 代码库中记录的某个流程返回已签名的网址。
  2. 将已签名的嵌入网址传递给嵌入 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

高级身份验证配置

您可以进一步配置身份验证端点,以允许自定义请求标头以及 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: {}
}

access_filters 参数已在 Looker 3.10 中移除,但仍需要在嵌入网址中使用空占位符。

问题排查

日志记录

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 = ''