本篇主要介绍electron-egg应用的mac版本如何实现公证.
一、前言
本篇主要介绍electron应用的mac版本如何实现公证,因为在MacOS 10.14.5之后,应用如果没有公证(简单说就是将安装包上传到Apple审查),那么就会弹出更严重的"恶意软件"提示框。如下图
二、实现公证的方法
准备工作
关于electron应用的公证,我们首先要做一些准备工作,
- 为你的应用生成一个bundle id。点击链接去生成一个应用的bundleId,如下图所示选择
进入之后选择App IDs
点击继续,之后选择APP
之后就是填下应用的描述、自定义bundleId,形似这样的就可以com.****.*****
。
生成的这个id就是你应用的appId。要注意打包应用后不能随意更改新的appId字段。否则会被认为是两个不同的应用而无法更新。下图中的id就是你生成的id,这两个要一样!
- 为你的账号生成一个特定于应用程序的密码。点击查看生成App专用密码的方法教程。 生密码成界面如图所示
生成你之后,你会得到一个类似于这种格式的密码****-****-****-****
。
- 你还需要有一个
xcode
。 - 公正时需要APPLE服务器通讯,需要验证网络连接正常。可以使用ping,也可以使用curl. 以下是在我本机上的测试状态。此状态下公正正常。
js
curl -I https://api.apple-cloudkit.com // 返回了 HTTP 响应头 HTTP/1.1 400 Bad Request
curl -I https://appstoreconnect.apple.com // 返回了 HTTP 响应头 HTTP/2 200
curl -I https://idmsa.apple.com // 返回了 HTTP 响应头 HTTP/1.1 403 Forbidden
ping api.apple-cloudkit.com // 返回 timeout
ping appstoreconnect.apple.com // 返回 ok
ping idmsa.apple.com // 返回 timeout
- 公正前需要确保所有二进制文件使用有效的开发者 ID 证书进行签名。
- 我的代码里面用到了很多第三方类库,好多.node二进制文件。需要确保
robotjs.node
二进制文件以及所有其他二进制文件都使用有效的开发者 ID 证书进行签名。同时确保签名包含安全时间戳。 - 筛选二进制文件的过程可能比较耗时,但好在只是一次性工作,后续几乎不需要改动。
- 可以使用
codesign
工具来签名二进制文件。 - 只对某个.node进行签名如下命令:
js
codesign --force --sign "Developer ID Application: Your Company Name (Team ID)" --deep --timestamp /path/to/robotjs.node
- 而要对所有二进制文件执行签名,就需要调用脚本了。 具体步骤:1) 在根目录下新建sign.sh。 2)遍历node_modules下所有.node执行签名。 3)遍历应用.app,执行签名。
js
# 设置你的开发者 ID 证书标识符
DEVELOPER_ID="Developer ID Application: Your Company Name (Team ID)"
# 递归查找并签名所有 .node 文件
find node_modules -name "*.node" | while read -r file; do
echo "Signing $file"
codesign --force --sign "$DEVELOPER_ID" --deep --timestamp "$file"
done
# 签名应用
APP_PATH="dist/your-app.app"
echo "Signing $APP_PATH"
codesign --force --sign "$DEVELOPER_ID" --deep --timestamp "$APP_PATH"
4) 运行脚本
js
chmod +x sign.sh
./sign.sh
- 特别说明:针对robotjs.node我本机会有一点异常。现象是debugger模式下正常,但是执行npm run build时会提示找不到robotjs.node。搜寻路径是/Users/sun/.npm/_prebuilds/25d508-robotjs-v0.6.0-electron-v109-darwin-arm64.tar.gz。没有找打其他方法,我就手工把这个文件造了出来。具体参见另一篇博客。
- 执行npm run build-m-arm64会在out下生成.app文件 ,.dmg文件, .zip文件。 以上 我们的准备工作就做完了。
接下来我们就要开始公正操作了。有两种方式,一种是通过手工命令行进行,适用于验证公正是否正常。一种是通过electron-notarize插件完成,适用与npm run build-xxx等打包方式。
方式一、通过命令行进行公正
准备工作:
- @1: 准备工作中获得的bundle id,即你的应用的appId。
- @2: 苹果开发者ID。(如果是公司的账号的话,需要最高权限的账号)
- @3: 准备工作中获得专用密码。
- @4: 证书提供者。
- @5: 你的dmg文件相对路径。(xxx.dmg)
手工公正命令
-
确认应用已正确签名并上传: 确保应用已正确签名,并且签名的身份与上传公证的身份一致。你可以使用以下命令检查签名:
bashcodesign -dvv /Users/sun/vs2024proj/ee/out/mac-arm64/ee.app
-
检查notarytool上传步骤: 确保应用已成功上传到苹果的公证服务,并且没有错误。可以使用以下命令重新上传应用:
bashxcrun notarytool submit /Users/sun/vs2024proj/ee/out/mac-arm64/ee.app --apple-id "your-apple-id" --password "your-app-specific-password" --team-id "your-team-id"
-
检查上传状态 : 使用
notarytool
检查上传的状态,确保上传成功且公证通过:
公正成功状态status: Accepted ;公正失败的状态是 status: Invalid和 status: Rejected。
js
xcrun notarytool history --apple-id "your-apple-id" --password "your-app-specific-password" --team-id "your-team-id"
Successfully received submission history.
history
--------------------------------------------------
createdDate: 2024-08-08T05:19:38.255Z
id: 2b50440e-f7b9-4397-b683-xxxxxxxxxxxx
name: ee.zip
status: Accepted
--------------------------------------------------
createdDate: 2024-08-08T04:08:56.663Z
id: e64d5a41-95ca-4e55-b0e4-yyyyyyyyy
name: ee.zip
status: Invalid
--------------------------------------------------
createdDate: 2024-05-30T03:30:50.815Z
id: ca4d5223-e1de-4d81-aaa9-zzzzzzz
name: ee.dmg
status: Rejected
- 检查详细错误报告: 可以通过以下命令查看详细的错误报告,找到具体的问题所在: 其中e64d5a41-95ca-4e55-b0e4-yyyyyyyyy是xcrun notarytool history返回的id. 想看失败的具体原因,可以访问上面返回的 LogFileURL 地址,会列出详细的错误信息.
python
xcrun notarytool log e64d5a41-95ca-4e55-b0e4-yyyyyyyyy --apple-id "your-apple-id" --password "your-app-specific-password" --team-id "your-team-id"
详细错误提示可以查看官网文档: mac公正错误官方文档。
公证有时候会很慢,习惯就好。。。
方式二、使用electron-notarize进行公证
这种方式是打包过程中自动去公证了。打好的包就是已经公证好的。
首先安装依赖
css
npm i electron-notarize
之后在build目录下创建build/notarization/notarize.js
文件,内容如下
javascript
const { notarize } = require("electron-notarize");
exports.default = async function notarizing(context) {
try {
const { electronPlatformName, appOutDir } = context;
if (electronPlatformName !== "darwin") {
return;
}
const appName = context.packager.appInfo.productFilename;
console.log(
`mac开始公正,公正工具notarytool,打包后应用地址:${appOutDir}/${appName}.app`
);
// appBundleId @1: 准备工作中获得的bundle id,即你的应用的appId。
// appleId @2: 苹果开发者ID。(如果是公司的账号的话,需要最高权限的账号)
// appleIdPassword @3: 准备工作中获得专用密码。
const result = notarize({
appBundleId: '方式一中的@1',
appPath: `${appOutDir}/${appName}.app`,
appleId: '方式一中的@2',
appleIdPassword: '方式一中的@3'
ascProvider: "your-team-id",
tool: "notarytool", // 公证工具 固定写法
teamId: "your-team-id",
});
console.log("mac公正 Notarization result:", result);
return result;
} catch (error) {
console.log("mac公正 出错了");
console.error(error);
}
};
之后在electron目录创建一个获取mac权限的文件electron/entitlements.mac.plist
内容如下
xml
<?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.app-sandbox</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.device.microphone</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.personal-information.addressbook</key>
<true/>
<key>com.apple.security.personal-information.calendars</key>
<true/>
<key>com.apple.security.personal-information.location</key>
<true/>
<key>com.apple.security.print</key>
<true/>
<key>com.apple.security.system.automation</key>
<true/>
<key>com.apple.security.system.bookmarks.app-scope</key>
<true/>
<key>com.apple.security.system.privacy.contacts</key>
<true/>
<key>com.apple.security.system.privacy.photos</key>
<true/>
</dict>
</plist>
最后在electron/config/builder.json
文件中添加如下配置
bash
{
productName: '小助手',
appId: 'com.example.app',
"afterSign": "build/notarization/notarize.js",
"mac": {
"icon": "build/icons/icon.icns",
"artifactName": "${productName}-${os}-${version}-${arch}.${ext}",
"darkModeSupport": true,
"hardenedRuntime": true,
"gatekeeperAssess": false,
"entitlements": "electron/entitlements.mac.plist",
"entitlementsInherit": "electron/entitlements.mac.plist",
"identity": ".... Co., Ltd. (your-team-id)"
},
}
如果公证不成功,先登录下开发者账号,看看是不是有协议没签署,签完了再打包公证。 还有就是这个公证的过程中,会很慢,耐心等待~
三、后记
以上两种公证方式都是可以的。
方式二就是会延长你的打包时间,我的项目目前打包时间约为6~7分钟左右。之前时间长的时候大概得有十几分钟。一般周五晚上(大家可能都是同一时间去公证了),感觉时间最长,可能是我们公司网速比较慢。。。
本篇完结 !撒花! 感谢观看! 希望能帮助到你!