OneSignalを利用してブラウザPush通知機能を追加した際に、HTTPSでのみ使用する前提のJSライブラリを入れたのが原因で、開発環境でもHTTPSを利用する必要が出た。
前提として、
- Mac OSX
- puma-dev
- webpacker
を利用している。puma-devはHTTPSに対応していて、自動でオレオレ証明書を作ってくれる。
webpack-dev-serverもHTTPSに対応している。次のようにconfig/webpacker.ymlのhttpsをtrueにするとhttps://example.com:8080/packs/application.js
といったURLでwebpackがコンパイルしたjsにアクセスできる。
development: <<: *default dev_server: host: example.com port: 8080 https: true
問題はオレオレ証明書の認証。chromeであれば毎回https://example.com:8080/packs/application.js
に直接アクセスして認証する必要がある。認証しないとJS読み込みでエラーになる。毎回やるのは大変面倒*1。
chromeでwebpack-dev-serverが生成した証明書を見ると「Subject Alt Nameが設定されていない」というエラーが出ていて、これにも対応する必要がありそう。puma-devはこのエラーは出ていなかった。
解決方法
次のコマンドで証明書を生成する
openssl req \ -newkey rsa:2048 \ -x509 \ -nodes \ -keyout server.pem \ -new \ -out server.pem \ -subj /CN=savanna.dev \ -reqexts SAN \ -extensions SAN \ -config <(cat /System/Library/OpenSSL/openssl.cnf \ <(printf '[SAN]\nsubjectAltName=DNS:savanna.dev')) \ -sha256 \ -days 3650
config/webpack/server.pem
など適当な場所に置く。
キーチェーンへこの証明書を登録し、「常に信頼」の設定にする。
次のようにしてwebpack-dev-serverを起動する
./bin/webpack-dev-server --cert ./config/webpack/server.pem --key ./config/webpack/server.pem
オプションを毎回つけるのがダルいのであればconfig/webpack/development.js
を次のようにしておく
const fs = require('fs'); // 省略 devServer: { clientLogLevel: 'none', https: { cert: fs.readFileSync('./config/webpack/server.pem'), key: fs.readFileSync('./config/webpack/server.pem'), }, // 省略
余談
ドメインがlocalhostでよければ chrome://flags/#allow-insecure-localhost を有効にすれば大丈夫そう(未確認)。
参考
- Self signed certificate no longer valid as of Chrome 58 · Issue #854 · webpack/webpack-dev-server
- CertSimple | Never see localhost HTTPS warnings again
*1:とりあえずの回避策として該当のJSライブラリを開発環境で読み込まないようにしようかとも思ったけど、バグの温床になりそうなのでやめた