作为 Web 开发者,最佳实践是使用尽可能低的信任度安全模型(例如渐进式 Web 应用 [PWA])来设计应用。这种方法可最大限度地扩大覆盖面,最大限度地减少您必须管理的安全开销,并为开发者和用户提供最大的灵活性。不过,由于 Web 默认情况下设计为安全,因此其保守的安全模型自然会限制对操作系统和某些强大的设备 API 的访问。
独立式 Web 应用 (IWA) 通过提供基于 Web 平台构建的隔离式、捆绑式、版本化、签名式且高度可信的应用模型来解决此问题。不过,在直接改用 IWA 之前,不妨考虑一个更循序渐进的步骤:将 PWA 与 Chrome 扩展程序相关联。此技术可在受管理的 ChromeOS 环境(例如受管理的用户会话、受管理的访客会话 [MGS] 或自助服务终端模式)中使用,让您的应用通过安全的消息传递使用较低级别的扩展程序 API。下图展示了这种渐进式方法:从标准 Web 应用开始,添加功能以使其成为可安装的 PWA,最后探索 PWA 和 Chrome 扩展程序路径以解锁其他 API。
如果您的应用需要使用高级功能,但即使使用 Chrome 扩展程序 API 也无法实现这些功能(例如受控框架或Direct Sockets API),那么迁移到独立式 Web 应用 (IWA) 是您的最佳选择。不过,虽然 IWA 可解锁强大的全新 Web 功能,但您可能仍然需要 Chrome 扩展程序独有的特定设备级 API,例如用于在自助服务终端模式下重启 ChromeOS 设备的 chrome.runtime.restart()。幸运的是,您可以使用与 PWA 完全相同的方法将 IWA 连接到 Chrome 扩展程序。以下步骤将详细介绍此方法。
实施过程分步说明
部署随播广告扩展服务
扩展程序通过 Chrome 管理控制台进行部署。您需要在相应部分中配置此设置,具体取决于目标环境(例如,对于自助服务终端模式,请依次前往设备 > Chrome > 应用和扩展程序 > 自助服务终端;对于用户和浏览器或受管理的访客会话,请前往相应标签页)。您可以自行托管扩展程序,并提供公开可访问的链接,也可以直接在 Chrome 应用商店中托管扩展程序。如需详细了解如何管理扩展程序,请参阅官方文档。
实现消息传递
扩展程序设置
如需接收和响应来自 Web 应用的消息,请公开一个后台脚本,该脚本会监听来自客户端(您的 Web 应用)的消息,然后将这些请求代理到相应的 API 调用。在以下示例中,当 Web 应用发送包含 methodName(值为 callRestart)的自定义消息对象时,系统会代理请求以重启 ChromeOS 设备。
Background.js
// message handler - extension code
chrome.runtime.onMessageExternal.addListener(function (request, sender, sendResponse) {
if (request.methodName == 'callRestart') {
chrome.runtime.restart();
}
});
您可以配置扩展程序的清单,以允许使用 externally_connectable 键对扩展程序进行外部函数调用,该键用于指定哪些网站和扩展程序可以调用扩展程序中的方法。如需详细了解 Chrome 扩展程序和清单 v3,请参阅官方文档。
如果您是从渐进式 Web 应用 (PWA) 进行连接,则需要在 matches 数组中列出托管应用的 HTTPS 标准网域。以下是为以自助服务终端模式运行的 PWA 配置的清单示例:
Manifest.json
{
"manifest_version": 3,
"name": "Restart your kiosk app",
"version": "1.0",
"description": "This restarts your ChromeOS device.",
"background": {
"service_worker": "background.js"
},
"externally_connectable": {
"accepts_tls_channel_id": false,
"matches": [
"*://developer.chrome.com/*"
]
}
}
如果您是从独立式 Web 应用 (IWA) 进行连接,则机制完全相同,但网址协议会发生变化。由于 IWA 经过安全打包,并且不在标准 Web 服务器上运行,因此它们使用自己的协议。您必须使用 isolated-app:// 方案添加 IWA 的源。
Manifest.json
{
"manifest_version": 3,
"name": "IWA Companion Extension",
"version": "1.1",
"description": "Companion extension for the IWA",
"background": {
"service_worker": "/scripts/background.js"
},
"externally_connectable": {
"matches": [
"isolated-app://*/*"
]
}
}
这是扩展程序中监听来自 PWA 或 IWA 的消息所需的最低代码量。
PWA 和 IWA 设置
如需从 Web 应用调用扩展程序,您需要知道其静态扩展程序 ID。此 ID 可在您安装 Chrome 扩展程序时显示的 chrome://extensions 页面上找到,也可在扩展程序上传后从 Chrome 应用商店中找到。这样,您的 Web 应用就可以指定要与之通信的确切扩展程序。之后,调用 chrome.runtime.sendMessage 并传入扩展程序 ID 以及要发送给扩展程序的消息。
const STATIC_EXTENSION_ID = 'abcdefghijklmnopqrstuvwxyz';
// found from chrome extensions page of chrome web store.
const callExtensionAPI = function (method) {
chrome.runtime.sendMessage(STATIC_EXTENSION_ID, {
methodName: method,
});
};
callExtensionAPI('callRestart');
如需详细了解如何将 Web 应用连接到扩展程序以进行消息传递,请参阅扩展程序文档。
演示
如需查看此实现的实际效果,请探索 IWA Kitchen Sink 代码库。此项目可作为各种 IWA 功能的综合试验平台,其中包含 Direct Sockets 和 Controlled Frame 等高信任度 API 的演示。它还提供了一个完整的 IWA 到 Chrome 扩展程序连接的有效示例。该代码库包含一个配套扩展程序示例和一个专用网页界面,展示了如何使用安全的消息传递来触发扩展程序专属方法。例如,您可以直接从独立式 Web 应用 (IWA) 中使用 chrome.identity.getProfileUserInfo() API 测试获取用户的个人资料信息。
总结
将 Web 应用连接到 Chrome 扩展程序可提供安全、渐进式的方式来解锁类似原生应用的功能。在设计应用架构时,请注意以下关键要点:
- 从 Web 开始:默认使用 PWA,以实现最佳覆盖面和最低的安全开销。
- 利用扩展程序弥合差距:对于深度集成的操作系统级功能(例如自助服务终端模式下的设备重启),请部署配套的 Chrome 扩展程序,并使用安全的消息传递机制将其连接到您的应用。
- 仅在需要时升级到 IWA:如果您需要使用 Direct Sockets、受控框架或任何其他仅限 IWA 的高信任度 API,请使用独立式 Web 应用。