自 macOS 10.14.5 开始,应用程序必须要经过签名以及公证(notarize),否则默认情况下便无法直接运行,会弹出类似下面的警告:
即:
“Appname.dmg” can’t be opened because Apple cannot check it for malicious software.
This software needs to be updated. Contact the developer for more information.
或者中文提示:
无法打开“Appname.app”,因为无法验证开发者。
macOS 无法验证此 App 不包含恶意软件。
要解决这个问题,就需要对 Electron 生成的程序进行签名和公证。官方的 文档 中有关于签名的说明,有多种方法,我使用的是 electron-builder 工具,重点参考了 Notarizing your Electron application 这篇文章,但因为时间及各个依赖库的变化,这些文档以及文章上的内容也有一些需要调整。下面是我踩了一些坑后的配置记录。
本文中的方法主要基于以下依赖版本:
"dotenv": "^8.2.0","electron": "^6.1.7","electron-builder": "^21.2.0","electron-notarize": "^0.2.1",
准备工作
首先,你需要一个有效的 Apple 开发者 账号,目前注册这个账号需要年费 $99。
有开发者账号,之后,需要在苹果官网的开发者后台 Certificates, Identifiers & Profiles 那儿申请若干证书以及要发布的 App 的 Identifiers 之类,这个和其他 App 的流程类似,此处不再赘述。下面假设你已经有了对应的证书以及应用 id。
electron-builder 配置
electron-builder 的配置中,mac 及 dmg 部分主要内容如下:
mac: { ..., gatekeeperAssess: false, identity: YOUR_IDENTITY, hardenedRuntime: true, entitlements: 'scripts/entitlements.mac.plist', entitlementsInherit: 'scripts/entitlements.mac.plist'},dmg: { ..., sign: false},
其中 entitlements.mac.plist 文件的内容为:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"> <dict> <key>com.apple.security.cs.allow-unsigned-executable-memory</key> <true/> </dict></plist>
到这儿,签名部分的配置就基本完成了。
公证(notarize)
这儿使用 Electron-notarize 对 Electron 程序进行公证。
首先要在你项目的 package.json 中最顶层添加以下配置:
"build": { "afterSign": "scripts/notarize.js"}
此 notarize.js 文件的内容类似:
require('dotenv').config()const {notarize} = require('electron-notarize')exports.default = async function notarizing (context) { const appName = context.packager.appInfo.productFilename const {electronPlatformName, appOutDir} = context if (electronPlatformName !== 'darwin') { return } let appPath = `${appOutDir}/${appName}.app` let {appleId, appBundleId, ascProvider} = process.env let appleIdPassword = `@keychain:Application Loader: ${appleId}` return await notarize({ appBundleId, appPath, ascProvider, appleId, appleIdPassword })}
注意其中有一些变量是从环境变量 process.env 中获取的。你可以使用传统的方式设置环境变量,也可以在当前工作目录下添加一个 .env 文件,其中以 key=value 的形式写入环境变量,一行一对 key/value 值。
几个变量的说明如下:
appleId
你的 Apple 开发者账号,即登录 https://developer.apple.com/ 的账号,通常是一个 Email 地址。
appleIdPassword
你的 Apple 开发者账号密码。出于安全考虑,建议 不要 直接将密码写在 .env 文件或环境变量中, 这儿 有一些安全建议,比如使用专用密码等。
我这儿用的是 @keychain:Application Loader: ${appleId} 这样的形式,你可以先在 Application Loader 等程序中用你的开发者账号登录一次,并让 Keychain 记住你的密码。由于现在最新版 Xcode 中已经不包含 Application Loader 了,你也可以在系统的 Keychain 中手动添加密码项。
ascProvider
此项是选填的,如果你的开发者账号与多个团队关联,运行时可能会遇到以下错误:
Your Apple ID account is attached to other iTunes providers. You will need to specify which provider you intend to submit content to by using the -itc_provider command. Please contact us if you have questions or need help.
此时,就需要指定此项参数,它的值就是你在开发者后台看到的 Team ID 的值。
完成
到此,配置基本就完成了,此时正常运行 electron-builder 的命令,即可在打包完成之后继续进行签名、公证工作。需要注意的是公证部分需要将程序压缩包传到 Apple 服务器,需要保证网络畅通。
如果一切顺利,一会儿之后你会收到 Apple 给你发的提醒邮件:
此时,表明你的 Electron 程序已经签名及公证成功了。
推荐阅读:苹果x和xr