嵌入 SDK 简介

Looker 的嵌入 SDK 是一个函数库,您可以将其添加到基于浏览器的 Web 应用的代码中,以便在 Web 应用中管理嵌入的 Dashboard、Look 和探索。嵌入 SDK 可通过以下方式简化嵌入:

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

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

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

  • Looker 嵌入 SDK 位于 Web 应用的客户端代码中,用于管理 Looker 嵌入上下文和内容。(嵌入 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)
  })

嵌入 SDK 演示文档页面上介绍了更完整的示例。

设置 Looker 嵌入 SDK

Looker 嵌入 SDK 使用流畅的接口模式。安装嵌入 SDK 后,您需要构建嵌入内容连接到嵌入内容

安装嵌入 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

构建嵌入内容

首先,使用您的网站服务器地址(以及可选的服务器上用于执行身份验证的端点)初始化 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,该 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 支持。为此,您可以将 options 对象传递给 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 中移除,但仍需要在嵌入网址中使用空占位符。

问题排查

日志记录

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