electronでのデスクトップアプリ開発の学習を久しぶりに続行しようかと思い立って、改めて推奨されるセキュリティを調べてみる。
リモートコンテンツを読み込む場合は「nodeIntegration: false」ってのは以前からあったけど「contextIsolation: true」は初耳。nodeIntegrationをオフる事でプリロードスクリプトにメインプロセスとレンダラープロセスを仲介させることになりますが、プリロードスクリプトはNode.jsにアクセスできるレンダラープロセスであるためこれも安全ではないんだとか。なのでcontextIsolationでプリロードスクリプトとレンダラーも分離してしまい、代わってAPIはcontextBridgeなるモジュールを通してプリロードからレンダラーへ公開するんだと。
なんかよう分からんようになってきました。穴ふさいだり、ちょっと開けたり大変です。contextBridge経由で使いたい分だけ解放してねって事でしょう、「全部拒否、必要なものだけ許可」、セキュリティのキホンですね。
contextBridge.exposeInMainWorld()
でAPI Keyを文字列で登録してその下に関数を公開するんですが、コード補完が効かなくなるよね。JavaScriptでやってるのに、型定義ファイル(*.d.ts)を作らなきゃいけなくなってまあメンドクサイ。
ようやくcontextBridgeを理解してelectronのクイックスタート。そうnode,chrome,electronの各バージョンを表示するだけのアレをセキュリティ対応したものに出来ました。バージョンを、表示する、だけ、のね。
ローカルで完結するアプリにcontextIsolationなんでイランけど。
//preload.js const {contextBridge,ipcRenderer} =require('electron') contextBridge.exposeInMainWorld( 'api', { //バージョンをipcMainへ問い合わせるだけ~ getVersions: () => { return ipcRenderer.invoke('get-version'); }, } )
ここからちょっと欲出して、このバージョン表示をvue.jsでやってみようという事になりまして、またここで問題発生。まずクイックスタートのレンダラーでは使用するindex.htmlには以下が設定されています。
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
vue.jsはテンプレートをコンパイルするためにeval関数を使用しているようで、Content-Security-Policyでunsafe-evelを設定しないと動きません。設定したらしたでelectronから怒られます。
回避策はというとvue.jsからテンプレートコンパイラを省いたvue.runtime.jsを使用する事です。だだしコンポーネント定義によるカスタムタグを使用できません、htmlへリアクティブデータを記述できません。表示はコンポーネントのrender関数でゴリゴリ記述する必要があります。
苦行の末、「nodeIntegration: false」「contextIsolation:true」「Content-Security-Policyはscript-src ‘self’」なアプリが出来上がりました。そうバージョンを表示するだけの。
bridgeの綴りまちごーた
@vue/cliとelectron-builderを使いましょう。