ElectronでSkyWayを使うときの問題点
ElectronでSkyWayを使う場合、問題になるのがXHR等でリクエストを投げる時、リクエストヘッダーにOriginフィールドがないまたはOriginフィールドの値が"file://"(WebSocket)になるということ。
SkyWayでは(APIキーごとに)登録したドメインからしか接続が行えない仕組みとなっていますが、ドメインの判定をこのリクエストヘッダーのOriginフィールドで行っているため、なんの対処をせずにSkyWayのプログラムを組んだElectronアプリで接続しようとするとどうしてもはじかれてしまいます。
1つの解決方法
すでに、Qiitaにこの問題の1つの解決方法が上がっております。
Electronでskyway.ioを使う
こちらの解決方法は、前段のXHR及びWebSocketをoriginキーの追加/変更が行えるisomorphic-fetchおよびwsに書き換えるという方法をとっています。
私も、同様のアプローチしか思いつきませんでした。
もっと手軽に解決する方法
ちょっと前置きが長くなりましたが、本題へ。
ElectronのGitHubのissuesにこんな投稿がありました。(スレッドの最後の投稿)
electron.session.defaultSession.webRequest.onBeforeSendHeaders((details, callback) => {
details.requestHeaders['Origin'] = 'electron://graphiql-app';
callback({ cancel: false, requestHeaders: details.requestHeaders });
});
おお!?っと思いこのコードを組み込んでみたら、XHR / fetch / WebSocket すべてにおいてOriginフィールド(が追加され)値が、"electron://graphiql-app"になりました。
Originフィールド追加/変更コードは、メインプロセスのコードに追加します。
ただし、アプリの'ready'イベントが発生する前にこのコードを実行すると、'ready'になる前ではダメ
的なエラーを吐くため、'ready'イベントハンドラー内にOriginフィールド追加/変更コードを追加します。
//...
app.on('ready', _ => {
electron.session.defaultSession.webRequest.onBeforeSendHeaders((details, callback) => {
details.requestHeaders['Origin'] = 'electron://localhost';
callback({
cancel: false,
requestHeaders: details.requestHeaders
});
});
//...
});
//...
これだけで、ElectronでSkyWayが使えるようになりました。
Originフィールドの値
Originフィールドの値は、URI(scheme+host)を設定するのですが、"sss://hhh"の形式でscheme,hostがそれぞれイリーガルなものでなければ自由に設定してもSkyWayからはじかれることはないようです。あと、大文字小文字の区別はしていないようで、SkyWayには"hoge"で登録していて、Originフィールドの値を"HOGE://HOGE"としても接続することができました。
##サンプルアプリ
サンプルアプリのソースをGitHubに上げましたので、cloneしてサクッと検証することができます。
Electron_SkyWay