自 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 開發者賬號,即登入 /file/2020/01/29/20200129124047_1314.jpg 的賬號,通常是一個 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 程式已經簽名及公證成功了。