Electron MacOs 打包 签名 公证(保姆级别)

发布时间 2023-04-25 13:44:16作者: 觉信
前述1
  1. MacOS 10.15 之前,应用如果没有进行签名,首次打开的时候就会出现“恶意软件”提示。
  2. 首先你要有一个苹果开发者账号 交完年费的那种
  3. arm64(M系列芯片) 架构打包需要增加兼容 x86 处理
  4. 开发者证书慎重申请,Developer ID Application 这个证书申请一个就够了,其他证书可以删除 这个得发邮件给苹果删除
前述2 证书介绍
  登录苹果开发者中心(https://developer.apple.com)Account首页,即有Certificates、Identifiers & Profiles项,管理苹果开发者账号的相关证书。进入页面后,左侧功能树共分为5组:Certificates、Keys、Identifiers、Devices、Provisioning Profiles。
Certificates:管理Development、Distribution、Push Development、Push Services证书,证书均以.cer结尾,创建后可以download,双击直接安装到钥匙串即可使用。(这个是最重要的)Tips:开发证书、发布证书生成数量有限(申请一个就够了 删除困难需要发邮件给苹果来申请删除),如需多人使用,建议由一人生成一组证书,然后导出.p12文件给其他成员使用即可,避免证书太多,管理混乱造成xcode配置方面的问题。若出现Maximum number of certificates generated的提示,revoke掉无用的证书。
Identifiers:主要是添加应用的 AppId
Devices:管理调试设备的udid,一个账号可以添加100台设备,可以使用(www.pgyer.com/udid)来获取udid或使用iTunes来获取udid,设备别名尽量写清楚哪台机器,以备以后删除。
Provisioning Profiles:描述文件的作用是描述了可由哪台电脑,把哪个APP安装到哪台手机上面。一个描述文件包含App ID、Devices、Certificates,类型分Development、Distribution两种。
 
一、 申请证书
证书多且重要且容易混乱,所以,找一个位置,新建一个文件夹来存放这些证书吧!比如新建一个名为 cerCenter 的文件夹。
  1. 申请一个本地证书
访达-其他-钥匙串访问 选择从 证书助理-从证书颁发机构请求证书...
0
第一栏写可用的电子邮箱(我的开发者账号就是邮箱);第二栏写名称 方便后期分辨这个证书;第三栏 CA 不用写;第四栏选择存到硬盘;
0
下一步成功后,将证书保存到新建的证书文件夹 cerCenter
下面我们会用到这个证书,来从 https://developer.apple.com/account/resources/certificates/list 申请下来重要的证书
  1. 打开 https://developer.apple.com/account/resources/certificates/list 左侧菜单栏切换到 Certificates
点击加号,选择 Developer ID Application 增加一个证书
0
点击 Choose File 来添加我们在步骤1申请的本地证书,之后我们所有的证书都要用到本地证书申请。
0
成功之后 就可以下载证书了,把这个证书也存放到新建的证书存放文件夹吧!(黄色箭头提示这个版本之后需要公证,红箭头点击下载)
0
把证书添加到钥匙串:钥匙串左侧先选择 登录;双击刚刚下载的证书,即可添加到钥匙串;右击选择 显示简介-信任-始终信任;
导出签名/公证需要的 p12 证书:右击钥匙串中的证书 - 导出....... - (存储为<自定义个名字比如 myP12Cer >;文件格式:个人信息交换(.p12)),存放位置还是选择我们新建的证书文件夹 cerCenter ;之后配置环境变量会用到它的路径!自此证书申请完毕,下面开始 Identifiers(填写一个 AppId) Devices(配置本机信息)
0
0
  1. Identifiers 配置 AppId
再打开苹果开发者中心,证书&描述,选择左侧菜单 Identifiers,点击加号 - 选择 App IDs
应用描述随便写一个,Bundle ID (Explicit)就是 AppId ,自定义一个 AppId -- 下一步 Continue
0
 
0
  1. Devices 把下图中三个对勾的写入 第一个选择 macOS 第二个取一个名称 第三个 在关于本机 系统信息 中找;
0
自此 所需要的资源准备完毕!下面开始本地配置信息
 
二、 本地配置证书信息
  1. 输入 sudo vim ~/.bash_profile 来打开配置文件
  2. 按 i 进入编辑状态
  3. 输入变量:CSC_KEY_PASSWORD 密码没有设置可以不填写
export CSC_LINK=/Users/xxx/cerCenter/xxx.p12 export CSC_KEY_PASSWORD=xxx
  1. 按 ESC 退出编辑;按 :wq 保存退出
  2. 刷新环境变量:source ~/.bash_profile
  3. 输入 env 查看环境变量配置结果
 
三、Electron 签名 公证 使用 electron-notarize
1、安装 npm i electron-notarize --save-dev
2、使用hardened runtime构建App 在 electron-builder mac配置选项中设置 hardenedRuntime: true; dmg 下 的 "sign": false(不对 dmg 文件签名)
3、禁用完整性检查 gatekeeperAssess: false (electron-builder使用的签名工具(electronic -osx-sign)会进行完整性检查以验证签名是否成功,MacOS 10.14.5 之前签名成功后返回 ture,但在 MacOS 10.14.5 之后签名完还有公证,会返回 false)
4、新建一个 scripts/notarize.js 文件。内容如下:
const { notarize } = require('electron-notarize'); exports.default = async function notarizing(context) { const { electronPlatformName, appOutDir } = context; if (electronPlatformName !== 'darwin') { return; } const appName = context.packager.appInfo.productFilename; return await notarize({ appBundleId: 'com.xxx.xxxxx', // AppId appPath: `${appOutDir}/${appName}.app`, // 不用改 appleId: 'gavrav16.developer16@gmail.com', // 开发者登录账号 appleIdPassword: 'grmz-asdf-fffaw-twoq', // App 专属密码 }); }
关于 App 专属密码:
https://appleid.apple.com/ 登录后选择 【App 专用密码】 --- 点击加号 增加一个,输入一个自定义名称 下一步 即可得到一个 苹果给的 随机生成的专属密码(这个密码其实可以理解为 App 开发者账户登录密码,只是它的权限更加专一,目前知道的仅在公证时使用到)
 
四、 兼容配置
本人使用的 M1 芯片属于 arm64 架构,所以在出包时 配置打出的包为 x86 也就是 x64 的:
mac: { hardenedRuntime: true, gatekeeperAssess: false, icon: 'build/electron-icon/icon.icns', category: 'public.app-category.utilities', target: { target: 'dmg', arch: 'x64' // x86 架构 } },
 
五、arm64 系列芯片打包 对 sqllit3 以及其他的 X86 兼容
package.json -- scripts 下的 rebuild 命令 增加环境变量 --arch=x64 指定 x86 架构
"rebuild": "electron-rebuild -f -w better-sqlite3 --arch=x64",
六、 其他(公证查询等)
xcrun altool --notarization-history 0 --username "aaa@163.com" --password "dfw-ffsap-rtyi-poiu"
0
 
七、vue.config.js 文件
 
const {
  defineConfig
} = require('@vue/cli-service')
const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')

const Icons = require('unplugin-icons/webpack')
const IconsResolver = require('unplugin-icons/resolver')

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = defineConfig({
  transpileDependencies: true,
  lintOnSave: false,
  outputDir: "dist/web",
  configureWebpack: {
    plugins: [
      new BundleAnalyzerPlugin(),
      AutoImport({
        resolvers: [
          // 自动导入element-plus组件
          ElementPlusResolver(),
          // 自动导入图标组件
          IconsResolver({
            prefix: 'Icon'
        })
        ],
      }),
      Components({
        resolvers: [
          // 自动导入element-plus组件
          ElementPlusResolver(),
          // 自动导入图标组件
          IconsResolver({
            prefix: false,
            enabledCollections: ['ep']
          })
        ],
      }),
      // 自动导入图标组件
      Icons({
        autoInstall: true,
      })
    ]
  },
  pluginOptions: {

    // vue-cli-plugin-electron-builder配置
    electronBuilder: {
      nodeIntegration: true,
      "buildDependenciesFromSource": true,
      "nodeGypRebuild": false,
      "npmRebuild": false,
      // externals: ['usb'],
      customFileProtocol: './',
      externals: ['better-sqlite3'],
      builderOptions: {
        // productName: 'xender_electron.exe',
        artifactName: "${productName}_${version}.${ext}",
        appId: "com.andou.musixmeta",
        afterSign: "scripts/notarize.js",
        publish: [{
          "provider": "generic",
          "channel": "latest",
          "url": ""
          //"url": "https://test-file.xendercdn.com/pcd/"
          //"url": "https://xendergif.web.app/",
        }],
        win: {
          requestedExecutionLevel: "requireAdministrator",
          icon: "build/electron-icon/icon.ico",
          // 图标路径 windows系统中icon需要256*256的ico格式图片,更换应用图标亦在此处
          target: [{
            // 打包成一个独立的 exe 安装程序
            target: "nsis",
            // target: "msi",
            // 这个意思是打出来32 bit + 64 bit的包,但是要注意:这样打包出来的安装包体积比较大,所以建议直接打32的安装包。
            arch: [
              "x64"
            //  'ia32'
            ],
          }, ],
        },
        linux: {
          icon: "build/electron-icon/icon.png",
          target: "AppImage",
        },
        "dmg": {
          "sign": false,
          "contents": [
            {
              "x": 410,
              "y": 150,
              "type": "link",
              "path": "/Applications"
            },
            {
              "x": 130,
              "y": 150,
              "type": "file"
            }
          ]
        },
        mac: {
          hardenedRuntime: true,
          gatekeeperAssess: false,
          // entitlements: "entitlements.mac.plist",
          // entitlementsInherit: "entitlements.mac.plist",
          icon: 'build/electron-icon/icon.icns',
          category: 'public.app-category.utilities',
          // target: ['dmg', 'zip', 'pkg'],
          // arch: [
          //   "arm64"
          // ],
          target: {
            target: 'dmg',
            arch: 'x64'
          }
        },
        files: ["**/*"],
        asar: true,
        nsis: {
          // 是否一键安装,建议为 false,可以让用户点击下一步、下一步、下一步的形式安装程序,如果为true,当用户双击构建好的程序,自动安装程序并打开,即:一键安装(one-click installer)
          oneClick: true,
          // 允许请求提升。 如果为false,则用户必须使用提升的权限重新启动安装程序。
         allowElevation: true,
          // 允许修改安装目录,建议为 true,是否允许用户改变安装目录,默认是不允许
          //allowToChangeInstallationDirectory: true,
          // 安装图标
          installerIcon: "build/electron-icon/icon.ico",
          // 卸载图标
          uninstallerIcon: "build/electron-icon/icon.ico",
          // 安装时头部图标
          installerHeaderIcon: "build/electron-icon/icon.ico",
          // 创建桌面图标
          createDesktopShortcut: true,
          // 创建开始菜单图标
          createStartMenuShortcut: true,
        },
    
        msi:{
          oneClick: false,            
        },
        extraResources: {
          from: 'icons/',
          to: 'icons/'
        }
      },
      chainWebpackMainProcess: (config) => {
        config.plugin("define").tap((args) => {
          args[0]["IS_ELECTRON"] = true;
          return args;
        });
      },
      chainWebpackRendererProcess: (config) => {
        config.plugin("define").tap((args) => {
          args[0]["IS_ELECTRON"] = true;
          return args;
        });
      },
      outputDir: "./dist/electron",
      mainProcessFile: "src/main/background.js",
      mainProcessWatch: ["src/main"],
    },
  },
})

 

 
参考链接
https://cloud.tencent.com/developer/article/1765152 Electron升级构建适配M1芯片Mac指南
https://juejin.cn/post/7182497884204433467 查看公证结果
https://www.npmjs.com/package/sqlite3 sqlite3 Format 多种编译配置(Format: napi-v{napi_build_version}-{platform}-{libc}-{arch})
https://juejin.cn/post/6844903954527027207 sqlite3 多种编译配置 –arch是cpu的位数