Embed SDK 简介

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

  • 提供嵌入内容的封装,而无需手动创建 HTML 元素。
  • 提供点对点通信,因此不存在跨帧通信。Embed SDK 使用专用消息渠道,处理托管网页与嵌入的 Looker 内容之间的跨网域消息传递。

如果没有 Embed SDK,您可以使用 dashboard:run:startpage:changed 等 JavaScript 事件调用或响应嵌入式 Looker 内容中的事件,嵌入式 JavaScript 事件文档页面介绍了这些事件。如果开发者使用 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

您可以通过位于 https://www.npmjs.com/package/@looker/embed-sdk 的节点软件包管理器 (NPM) 获取 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

构建嵌入内容

首先,使用您的 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 Embed SSO 示例 GitHub 代码库中记录的其中一个流程返回签名网址。
  2. 将已签名的嵌入网址传递给 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

高级身份验证配置

您可以进一步配置身份验证端点,以允许自定义请求标头和 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 使用 debug 进行日志记录。您可以使用以下命令在浏览器控制台中启用日志记录功能:

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