尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Brave browser-laptop 自动更新机制与 macOS 代码签名实战指南

Brave browser-laptop 自动更新机制与 macOS 代码签名实战指南 桌面应用【免费下载链接】browser-laptop[DEPRECATED] Please see https://github.com/brave/brave-browser for the current version of Brave项目地址https://gitcode.com/gh_mirrors/br/browser-laptop点击查看免费下载本篇技术指南围绕 browser-laptopBrave 桌面浏览器现已迁移至 brave/brave-browser 的旧版本仓库的自动更新Auto Update体系展开核心覆盖两条主线一是基于 Electron/Squirrel 的更新检查、下载与安装的完整链路及其源码实现二是 macOS 平台 dmg 构建产物在上线前必须完成的代码签名Code Signing全流程。读完本文你将掌握本仓库中更新服务的工作原理app/updater.js、codesign签名与验证命令的完整用法、IDENTIFIER证书标识符等关键概念并能复现从证书准备到签名验证、再到发布部署的完整工程流程。一、自动更新机制总览Overview原文档对自动更新的定义非常简洁自动更新提供了一系列服务允许浏览器自动检查更新并在新版本可用时自动应用变更。落到实现层面这一能力由 Electron 框架内置的autoUpdater提供而autoUpdater在 macOS / Windows 上的底层引擎正是SquirrelSquirrel.mac / Squirrel.Windows。在 app/updater.js 中可以清楚看到const autoUpdater electron.autoUpdater const app electron.app也就是说browser-laptop 本身并不重复实现下载安装包、替换可执行文件这类系统级工作而是将这一层委托给 Squirrel 运行时项目自身聚焦于构建更新检查 URL按渠道 / 版本 / 平台拼接按启动延时与周期频率调度检查与自建的更新元数据服务通信获取最新版本信息把 Squirrel 反馈的状态下载中、可用、无更新、错误等映射为浏览器内的更新状态机驱动 UI 提示在用户确认后调用autoUpdater.quitAndInstall()完成退出重装。文档同时强调了一个 macOS 关键约束手工安装 dmg 后后续更新自动进行但 dmg 产物的各组件必须先完成数字签名更新系统才会执行新版本检查与安装。这一点在第五节会有完整演练。二、更新链路源码剖析从启动初始化到状态机自动更新并非凭空发生它在浏览器启动时被显式初始化。在 app/index.js 中应用加载完持久化状态后立即调用updater.init( process.platform, process.arch, process.env.BRAVE_UPDATE_VERSION || app.getVersion(), process.env.BRAVE_ENABLE_PREVIEW_UPDATES ! undefined ) // 菜单入口触发的手动检查 process.on(messages.CHECK_FOR_UPDATE, () updater.checkForUpdate(true)) ipcMain.on(messages.CHECK_FOR_UPDATE, () updater.checkForUpdate(true))updater.init拿到平台、架构、版本号与是否接受预览版标志后在 app/updater.js 中依次完成重置更新状态、拼接更新 URL、注册定时任务、设置 Squirrel 的 feed URL。1. 更新 URL 的构建与平台映射app/updater.js 定义了一份process.platform到更新 API 标识的映射表var platforms { darwin: osx, win32x64: winx64, win32ia32: winia32, linux: linux }在此基础上updateUrl() 拼出完整的更新端点exports.updateUrl function (updates, platform, arch) { if (platform win32) { platform platform arch // win32x64 / win32ia32 } platformBaseUrl ${updates.baseUrl}/${Channel.channel()}/${version}/${platforms[platform]} ... }URL 形如{baseUrl}/{channel}/{version}/{platform}其中渠道与版本是更新路径的两个关键维度。渠道取自 app/channel.js优先级为构建配置buildConfig.channel→ 环境变量CHANNEL→ 默认空串dev合法取值集合为dev / beta / stable / developer / nightly / 。2. 检查频率调度scheduleUpdates() 设置了两种检查时机具体间隔由 js/constants/appConfig.js 中的updates配置段控制配置项默认值含义appUpdateCheckFrequency1000 * 60 * 601 小时周期检查频率通过setInterval触发runtimeUpdateCheckDelay1000 * 60 * 2启动后 2 分钟启动后首次检查的延时通过setTimeout触发两个配置均为 0 或 falsy 时对应定时任务不会注册。3. 元数据请求与隐私保护设计真正向更新服务器发起请求的是 requestVersionInfo()。值得注意的是该请求采用了一种隐私优先的报文设计不向服务器传递可识别个人的信息而是由 paramsFromLastCheckDelta() 生成一组布尔标志表达距离上次检查的时间差daily距上次检查是否超过一天weekly上周是否未检查monthly上月是否未检查first浏览器是否从未发起过更新请求woi安装周week of installationref来自updateState.getUpdateProp(state, referralPromoCode)的推广码无则none。服务器对请求的响应语义如下返回204表示无可用更新200且携带 JSON body 则触发UPDATE_META_DATA_RETRIEVED事件并进入下载处理回调 downloadHandler()网络错误或配置错误则向autoUpdater发出error事件。4. 更新状态机与 UI 可见性Squirrel 与元数据请求产生的事件会被统一收敛到状态机。状态全集定义在 js/constants/updateStatus.jsUPDATE_NONE、UPDATE_CHECKING、UPDATE_AVAILABLE、UPDATE_AVAILABLE_DEFERRED、UPDATE_DOWNLOADING、UPDATE_NOT_AVAILABLE、UPDATE_ERROR、UPDATE_APPLYING_RESTART、UPDATE_APPLYING_NO_RESTART。app/updater.js 中注册了update-downloaded、UPDATE_AVAILABLE、UPDATE_NOT_AVAILABLE、error四个事件的处理器逐一映射到上述状态。UI 何时展示更新提示由 app/common/state/updateState.js 的isUpdateVisible决定后台检查非 verbose时只允许更新可用提示打扰用户其余检查中、下载中等状态一律静默避免频繁打扰。5. 下载完成后的安装与关闭竞态处理下载完成后用户确认即调用updater.quitAndInstall()app/updater.js交由 Squirrel 完成退出与重装。为防止用户下载完但不想立刻重启的场景被误杀app/sessionStoreShutdown.js 在关闭流程里做了状态标记Windows 下置为UPDATE_APPLYING_RESTARTSquirrel 检测到应用正在关闭避免用户二次手动打开其他平台置为UPDATE_APPLYING_NO_RESTART随后在退出回调中统一调用updater.quitAndInstall()。这也解释了状态枚举里两个APPLYING_*值的用途——它们在 app/common/state/updateState.js 中被判定为不可见状态。三、macOS 更新约束Squirrel.mac 与签名前提原文档明确指出 macOS 平台的更新形态手工安装之后所有后续更新将通过 ElectronAtom框架提供的 Squirrel.mac 服务自动进行。构建出的 dmg 二进制产物必须完成组件数字签名更新系统才会检查并安装新版本。也就是说签名是 macOS 自动更新的前置条件——未签名的 dmg 产物无法被更新通道识别和接受。这与 macOS 的 Gatekeeper / 代码签名体系一致Squirrel.mac 在检查更新时会校验新版本的签名与 sealed resources 完整性。四、签名相关术语定义原文档给出了三个贯穿签名流程的核心定义整理如下术语定义说明USER当前登录用户命令示例路径中的用户目录占位符CERTIFICATE由第三方签发的文件用于对二进制进行数字签名并确认其来源即 Apple Developer 证书IDENTIFIER证书中的组织标识符10 位大写字母数字形如12345ABCDEcodesign 用--sign指定IDENTIFIER是签名成败的关键它必须与 Keychain 中证书的 Team Identifier / Organizational Identifier 一致否则codesign会报错找不到匹配的签名身份。五、macOS 代码签名四步实战原文档给出的签名流程共四步以下按序完整展开并补充每步的要点与当前仓库的对应物。步骤 1创建并下载开发者证书登录 developer.apple.com创建并下载开发者证书得到.cer格式文件使用 macOS 自带的Keychain Access钥匙串访问程序将证书导入login登录分区Keychain Access 默认会处理.cer文件。步骤 2确保存在关联的私钥确认步骤 1 安装的证书已关联一个私钥证书条目下会展开并标注 private key生成私钥.p12文件是多步骤过程需要访问 developer.apple.com 门户并操作开发机原文档引用了第三方 p12 生成教程appfurnace 的《How do I make a p12 file?》一文可按该思路在开发者门户中导出若已持有私钥将其导入 Keychain Access并确保与开发者证书绑定在同一条目下。要点私钥与证书必须在同一登录钥匙串条目中关联codesign才能找到可用的签名身份。步骤 3构建待签名的未压缩应用产物原文档给出的命令为npm run build-darwin需要说明的是当前仓库package.json见 package.json中实际保留的构建脚本入口是build-installernode ./tools/buildInstaller.js与build-packagenode ./tools/buildPackage.js产物目录名为Brave-darwin-x64/。无论采用哪条构建入口产物都应包含完整的.app结构与Contents/Frameworks目录以便执行后续签名。步骤 4对产物执行 codesign签名分为两层按目录层级依次执行以下命令为原文档原样第一层——Frameworks 目录路径Brave-darwin-x64/Contents/Brave.app/Contents/Frameworkscodesign --deep --force --strict --verbose --sign IDENTIFIER *第二层——app 根目录路径Brave-darwin-x64codesign --deep --force --strict --verbose --sign IDENTIFIER Brave.app/命令参数含义速查参数作用--deep对 app 内部所有嵌套组件Frameworks、Helpers 等递归签名--force覆盖已存在的签名--strict启用严格模式校验--verbose输出详细签名日志--sign IDENTIFIER指定签名身份证书组织标识符替代方案一键执行签名脚本文档指出以上两步可以通过仓库自带脚本一次性完成签名身份以环境变量方式注入IDENTIFIER12345ABCDE npm run build-installer脚本入口是 tools/buildInstaller.js。从源码看该脚本在 Darwin 分支下会依次完成校验IDENTIFIER是否已设置未设置直接raiseError(IDENTIFIER needs to be set to the certificate organization)见 tools/buildInstaller.js→ 为 WidevineBrave Framework生成并校验签名 → 对 Frameworks 目录执行codesign --deep --force --strict --verbose --sign $IDENTIFIER *→ 对Brave.app/执行同一签名命令 → 依据渠道res/{channel}/builderConfig.json打包 dmg/pkg → 用ditto生成用于更新的 zip 产物dist/Brave-{version}.zip。也就是说npm run build-installer把签名 打包 生成更新 zip串成了单条流水线正是文档第 4 步命令被脚本化的落地实现。六、签名结果验证Check签名是否成功必须用验证命令确认而不是凭感觉。原文档给出两段验证手段与示例输出下面完整保留并逐段解读。1. 详细信息校验codesign -dvvcodesign -dvv Brave.app/示例输出原文档摘录路径中的USER为当前登录用户占位Executable/Users/USER/repos/browser-electron/Brave-darwin-x64/Brave.app/Contents/MacOS/Electron Identifiercom.electron.XXXX Formatbundle with Mach-O thin (x86_64) CodeDirectory v20200 size202 flags0x0(none) hashes33 locationembedded Signature size4385 Authority3rd Party Mac Developer Application: XXXX Software, Inc. (IDENTIFIER) AuthorityApple Worldwide Developer Relations Certification Authority AuthorityApple Root CA Signed TimeDec 9, 2015, 5:29:13 PM Info.plist entries21 TeamIdentifierIDENTIFIER Sealed Resources version2 rules12 files58929 Internal requirements count1 size208解读要点Authority链展示了完整的证书信任链应用证书 → Apple Worldwide Developer Relations → Apple Root CA这是签名被系统信任的基础TeamIdentifier应与你的IDENTIFIER一致Sealed Resources version2是文档特别强调的检查点version 必须是 2若显示为 1 则说明签名方式不合规例如被旧工具链签名会破坏 Squirrel 更新校验。2. 深度验证codesign --deep-verify --verbose4codesign --deep-verify --verbose4 Brave.app/该命令对 app 内所有嵌套组件逐一校验示例输出中每个组件都有--prepared:与--validated:两行记录涵盖Brave Helper.app含 EH / NP 变体及其Contents/MacOS可执行文件ReactiveCocoa.framework、Mantle.framework、Squirrel.frameworkSquirrel 是自动更新引擎本身位于Contents/FrameworksElectron Framework.framework。全部组件校验完成后最终两行结论性输出是Brave.app/: valid on disk Brave.app/: satisfies its Designated Requirement只有同时满足磁盘上有效与满足 Designated Requirement签名才算真正通过更新通道才会接纳该产物。七、验证通过后的更新入口签名完成且 dmg 安装后用户即可通过菜单入口触发更新检查。回顾 app/index.js主进程同时监听了process事件与ipcMain的CHECK_FOR_UPDATE消息均调用updater.checkForUpdate(true)verbosetrue即允许弹出检查 UI。更新过程中的日志会被追加写入用户数据目录下的updateLog.log见 app/updater.js格式为ISO 时间戳 - 内容内容包括platformBaseUrl、updateUrl、lastCheckYMD等诊断信息排查更新问题时是首选的第一手日志。八、Windows x64 与 Linux 平台现状原文档在 Windows x64 一节仅标注了TODO说明签名与安装细节在当时尚未成文。但更新链路并非完全空白从 app/updater.js 源码结构看Windows 更新逻辑已具备Windows 的更新 URL 不使用统一拼接而是走独立的winBaseUrl${winUpdateHost}/multi-channel/releases/CHANNEL/winUpdateHost默认https://download.brave.com并将架构后缀拼在其后app/updater.js、js/constants/appConfig.jsWindows 平台在拿到元数据后会先读取metadata.braveURL重新设置 feed URL 再发起checkForUpdates()app/updater.js这暗示 Windows 更新端点与元数据服务是分离的两套地址关闭流程中对 Windows 单独标记UPDATE_APPLYING_RESTART以避免用户二次手动启动app/sessionStoreShutdown.js。从源码结构看Linux 平台同样会构造更新端点platforms.linux linux且走platformBaseUrl分支但自动更新的安装动作仍以 Squirrel 支持的 macOS / Windows 为完整闭环。九、更新部署Deploying Updates原文档关于部署的指引指向一个独立的更新服务端项目brave/vault-updater。也就是说browser-laptop 仓库只负责客户端检查 签名 打包新版本 zip / dmg 产物的托管、版本元数据的对外提供由该独立的更新服务承担。客户端请求的元数据端点即 js/constants/appConfig.js 中的baseUrl: ${updateHost}/1/releasesupdateHost默认https://laptop-updates.brave.com。发布流程通常为签名打包产物 → 上传至更新服务 → 更新服务对外发布新版本元数据 → 客户端周期检查命中后完成升级。十、更新相关配置与环境变量速查综合 js/constants/appConfig.js、app/channel.js 与 app/index.js与自动更新相关的全部可调参数汇总如下配置 / 环境变量默认值作用updates.appUpdateCheckFrequency1 小时周期更新检查间隔updates.runtimeUpdateCheckDelay启动后 2 分钟启动首查延时updates.autoAppUpdatefalse是否在更新加载前静默不通知用户updates.autoRuntimeUpdatefalse运行时更新是否静默updates.baseUrl${BRAVE_UPDATE_HOST}/1/releasesmacOS/Linux 更新元数据端点updates.winBaseUrl${BRAVE_WIN_UPDATE_HOST}/multi-channel/releases/CHANNEL/Windows 独立更新端点BRAVE_UPDATE_HOSThttps://laptop-updates.brave.com覆盖更新元数据主机BRAVE_WIN_UPDATE_HOSThttps://download.brave.com覆盖 Windows 更新主机BRAVE_UPDATE_VERSION取app.getVersion()覆盖用于更新 URL 的版本号BRAVE_ENABLE_PREVIEW_UPDATES未定义定义后接受预览版更新URL 追加accept_previewtrueCHANNEL构建配置或空串dev指定发布渠道合法值dev/beta/stable/developer/nightlyIDENTIFIER签名时无签名身份build-installer的必需环境变量适用前提上述行为基于当前仓库代码版本0.27.3见 package.json验证。该仓库已标记为 DEPRECATED当前版本见 brave/brave-browser本文所有命令与路径均以本仓库实际内容为准。结语自动更新看似是调一个 Squirrel API那么简单但真正让它在生产环境稳定运转靠的是三条链路签名链证书、私钥、codesign 与验证输出、调度链启动延时 周期检查 隐私参数化的元数据请求与状态链更新状态机、UI 可见性与关闭时的重启安装竞态处理。本文从 docs/autoUpdates.md 出发逐一打通了这三条链路在仓库中的实现与配置无论是想复现 macOS 签名发布流程还是排查更新不生效的问题先看updateLog.log再核对渠道、版本与签名都能在本文与所列源码路径中找到落点。赞分享桌面应用【免费下载链接】browser-laptop[DEPRECATED] Please see https://github.com/brave/brave-browser for the current version of Brave项目地址https://gitcode.com/gh_mirrors/br/browser-laptop点击查看免费下载相关推荐3步告别数据混乱DataEase开源BI工具让数据可视化如此简单3步告别数据混乱DataEase开源BI工具让数据可视化如此简单 你是否曾为海量数据而头疼面对Excel表格里密密麻麻的数字却无法快速洞察业务趋势每天需数据分析数据可视化后端前端brave/browser-laptop事件处理机制从用户输入到状态更新brave/browser laptop事件处理机制从用户输入到状态更新 事件处理机制概述 Brave浏览器的事件处理机制是连接用户操作与应用状态变化的核心桥桌面应用brave/browser-laptop代码质量保障ESLint配置与代码审查brave/browser laptop代码质量保障ESLint配置与代码审查 在开源项目开发中代码质量保障是确保项目可维护性和稳定性的核心环节。brave桌面应用上一篇pdfme模板设计器完全指南可视化创建PDF模板下一篇Apache SeaTunnel Druid Sink基于 Native Batch Indexing Task 的 Druid 写入连接器详解创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表