Electron 功能开关
打包时功能开关
什么是功能开关?
对于一部分 Electron 功能,为整个应用程序禁用某些功能是有意义的。例如,99% 的应用不使用 ELECTRON_RUN_AS_NODE
,这些应用希望能够发布一个不具备该功能的二进制文件。我们也不希望 Electron 用户从源代码构建 Electron,因为这既是一个巨大的技术挑战,也需要花费大量时间和金钱。
功能开关(Fuses)是解决此问题的方案,从高层面看,它们是 Electron 二进制文件中的“魔力位”,可以在打包 Electron 应用时翻转以启用/禁用某些功能/限制。由于它们是在打包时、在您对应用进行代码签名之前翻转的,因此操作系统通过 OS 级别的代码签名验证(Gatekeeper / App Locker)来确保这些位不会被翻转回来。
当前功能开关
runAsNode
默认值: 已启用
@electron/fuses: FuseV1Options.RunAsNode
runAsNode 功能开关决定是否遵守 ELECTRON_RUN_AS_NODE
环境变量。请注意,如果此功能开关被禁用,主进程中的 process.fork
将无法按预期工作,因为它依赖此环境变量。相反,我们建议您使用实用工具进程,这适用于许多需要独立 Node.js 进程的用例(如 Sqlite 服务器进程或类似场景)。
cookieEncryption
默认值: 已禁用
@electron/fuses: FuseV1Options.EnableCookieEncryption
cookieEncryption 功能开关决定磁盘上的 cookie 存储是否使用 OS 级加密密钥进行加密。默认情况下,Chromium 用于存储 cookie 的 sqlite 数据库以明文形式存储值。如果您希望确保应用中的 cookie 以与 Chrome 相同的方式加密,则应启用此功能开关。请注意,这是一个单向转换,如果启用此功能开关,现有的未加密 cookie 将在写入时被加密,但如果随后再次禁用此功能开关,则您的 cookie 存储将实际上损坏且无法使用。大多数应用可以安全地启用此功能开关。
nodeOptions
默认值: 已启用
@electron/fuses: FuseV1Options.EnableNodeOptionsEnvironmentVariable
nodeOptions 功能开关决定是否遵守 NODE_OPTIONS
和 NODE_EXTRA_CA_CERTS
环境变量。NODE_OPTIONS
环境变量可用于向 Node.js 运行时传递各种自定义选项,通常在生产环境中不被应用使用。大多数应用可以安全地禁用此功能开关。
nodeCliInspect
默认值: 已启用
@electron/fuses: FuseV1Options.EnableNodeCliInspectArguments
nodeCliInspect 功能开关决定是否遵守 --inspect
、--inspect-brk
等标志。禁用时,它还会确保 SIGUSR1
信号不会初始化主进程检查器。大多数应用可以安全地禁用此功能开关。
embeddedAsarIntegrityValidation
默认值: 已禁用
@electron/fuses: FuseV1Options.EnableEmbeddedAsarIntegrityValidation
embeddedAsarIntegrityValidation 功能开关在 macOS 上切换一个实验性功能,该功能在加载 app.asar
文件时验证其内容。此功能旨在对性能影响最小,但可能会略微减慢从 app.asar
压缩包内的文件读取速度。
有关如何使用 asar 完整性验证的更多信息,请阅读ASAR 完整性文档。
onlyLoadAppFromAsar
默认值: 已禁用
@electron/fuses: FuseV1Options.OnlyLoadAppFromAsar
onlyLoadAppFromAsar 功能开关改变了 Electron 用于定位应用代码的搜索系统。默认情况下,Electron 将按以下顺序搜索:app.asar
-> app
-> default_app.asar
。当此功能开关启用时,搜索顺序变为单个条目 app.asar
,从而确保与 embeddedAsarIntegrityValidation
功能开关结合使用时,无法加载未验证的代码。
loadBrowserProcessSpecificV8Snapshot
默认值: 已禁用
@electron/fuses: FuseV1Options.LoadBrowserProcessSpecificV8Snapshot
loadBrowserProcessSpecificV8Snapshot 功能开关更改了浏览器进程使用的 V8 快照文件。默认情况下,Electron 的进程都使用相同的 V8 快照文件。当此功能开关启用时,浏览器进程使用名为 browser_v8_context_snapshot.bin
的文件作为其 V8 快照。其他进程将使用它们通常使用的 V8 快照文件。
V8 快照有助于提高应用启动性能。V8 允许您获取已初始化堆的快照,然后重新加载它们,以避免初始化堆的开销。
对渲染器进程和主进程使用单独的快照可以提高安全性,特别是要确保渲染器不使用启用了 nodeIntegration
的快照。详见#35170。
grantFileProtocolExtraPrivileges
默认值: 已启用
@electron/fuses: FuseV1Options.GrantFileProtocolExtraPrivileges
grantFileProtocolExtraPrivileges 功能开关改变了从 file://
协议加载的页面是否获得超出传统 Web 浏览器所提供特权。这种行为在 Electron 的早期版本中是 Electron 应用的核心,但现在已不再需要,因为应用现在应该通过自定义协议提供本地文件。如果您不从 file://
提供页面,则应禁用此功能开关。
此功能开关赋予 file://
协议的额外特权在下面不完全记录:
file://
协议页面可以使用fetch
加载其他file://
资源file://
协议页面可以使用 service workers- 无论沙盒设置如何,
file://
协议页面都对同样运行在file://
协议上的子 frame 拥有通用访问权限
如何切换功能开关?
简单方法
我们提供了一个便捷的模块,@electron/fuses
,可以轻松切换这些功能开关。请查看该模块的 README 文件以了解更多使用细节和潜在错误情况。
const { flipFuses, FuseVersion, FuseV1Options } = require('@electron/fuses')
flipFuses(
// Path to electron
require('electron'),
// Fuses to flip
{
version: FuseVersion.V1,
[FuseV1Options.RunAsNode]: false
}
)
您可以使用 fuses CLI 验证功能开关是否已翻转或检查任意 Electron 应用的功能开关状态。
npx @electron/fuses read --app /Applications/Foo.app
复杂方法
快速术语表
- 功能开关线 (Fuse Wire):Electron 二进制文件中用于控制功能开关的字节序列
- 哨兵 (Sentinel):用于定位功能开关线的静态已知字节序列
- 功能开关模式 (Fuse Schema):功能开关线的格式/允许值
手动翻转功能开关需要编辑 Electron 二进制文件,并修改功能开关线以使其成为表示所需功能开关状态的字节序列。
在 Electron 二进制文件中的某个位置,会有一系列字节,看起来像这样:
| ...binary | sentinel_bytes | fuse_version | fuse_wire_length | fuse_wire | ...binary |
sentinel_bytes
始终是这个确切的字符串dL7pKGdnNz796PbbjQWNKmHXBZaB9tsX
fuse_version
是一个单字节,其无符号整数值表示功能开关模式的版本fuse_wire_length
是一个单字节,其无符号整数值表示后续功能开关线中的功能开关数量fuse_wire
是一个包含 N 个字节的序列,每个字节表示一个功能开关及其状态。- "0" (0x30) 表示功能开关已禁用
- "1" (0x31) 表示功能开关已启用
- "r" (0x72) 表示该功能开关已被移除,将字节更改为 1 或 0 将无效。
要翻转功能开关,请在功能开关线中找到其位置,并根据所需状态将其更改为“0”或“1”。
您可以在这里查看当前模式。