mkcertを使ってlocalhostをHTTPS化して開発する

以前も同じ内容の記事を書きましたが、auth0のブログにあった方法のほうが便利そうなので、試してみました。 auth0のブログの内容をちょこちょこ翻訳しながら紹介します。

元になったブログ記事はこちら

Why and How to Use HTTPS in Your Local Development Environment

auth0はOAuth・OIDCなどの認証認可基盤とよばれるようなシステムの開発会社です。認証認可(サインインやログインなど)に関するブラウザ等の機能(例:FIDO2認証)にはHTTPSが必要とされることがあり、ローカル開発環境にもHTTPSが必要なのでしょう。

試した環境

  • Windows 10
  • Chocolatey v0.12.1
    • mkcertをインストールするために必要
  • mkcert v1.4.3
    • HTTPSに必要な証明書などを作成するツール
  • Node.js v12.22.5

手順

mkcertのインストール

HTTPSに必要な証明書などを作成するツールmkcertをインストールします。 OpenSSLが最もよく知られていて最も強力ですが、公開鍵基盤について充分な知識が必要なため、今回はmkcertを使うとのことです。

mkcertのインストール方法はmkcertのGitHubに記載されているとおりですが、WindowsなのでChocolateyを使います。WSLを使ってLinux版のインストール手順で実行することもできそうですね。

Chocolateyのインストール方法も公式サイトに記載されているとおりで出来ました。

Chocolatey Software | Installing Chocolatey

PowerShellを管理者権限で起動して以下のコマンドを実行

$ Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))

完了するまで待ち、完了したら以下のコマンドで確認します。

$ choco

バージョン情報が帰ってくれば完了です。 改めてmkcertのインストールをします。

$ choco install mkcert

インストールが完了すると、インストール成功という情報とバージョンの情報が返ってきました。

mkcertでローカル認証局を作成する

以下のコマンドを実行します。

$ mkcert -install

ポップアップ画面で以下の画像のようなセキュリティ警告が表示されました。 どうやら、Firefoxの機能・設定に関する警告(Setting Up Certificate Authorities (CAs) in Firefox | Firefox for Enterprise Help)であり、Firefoxを使わないのであれば無視してよいそうです。

mkcert

今回は「はい」を選ぶことにしました。

証明書の作成

まず、Node.js上に構築するアプリのフォルダを作成します。フォルダ名はブログ記事の内容と同じにしてmy-secure-appとします。 作成したフォルダ内に入ります。

フォルダ内で以下のコマンドを実行し、localhostというホスト名に対する証明書(localhost.pem)と秘密鍵localhost-key.pem)を作成します。

$ mkcert localhost

サーバのソースコード

先のmy-secure-appフォルダ内にserver.jsというファイルを作成し、以下のコードを書いて保存します。

const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('localhost-key.pem'),
  cert: fs.readFileSync('localhost.pem')
};

https.createServer(options, function (req, res) {
  res.writeHead(200);
  res.end("I'm HTTPS-enabled!");
}).listen(8080);

console.log("The server is listening to port 8080 with HTTPS enabled.");

実行

my-secure-appフォルダ内でPowerShellコマンドプロンプトを立ち上げ、以下のコマンドを入力します。

$ node server.js

これによってhttps://localhost:8080でサーバがアクセスを待っています。 実際に上記のURLをChromeに入力すると、「I'm HTTPS-enabled!」というメッセージがブラウザに表示されます。

アドレスを変更してhttp://localhost:8080にしてHTTPで接続を試みると、「ページは動作していません」というブラウザのエラー画面になります。

また、Firefoxhttps://localhost:8080にアクセスを試みると、以下の画像のように警告が表示されます。証明書が無効になっているHTTPSのサイトにアクセスしたときに表示される画面と同じです。 mkcertでローカル認証局を作成したときの警告と関連しており、Firefoxがこの認証局を信頼していないということが原因です。

Firefox

対策としては、Setting Up Certificate Authorities (CAs) in Firefox | Firefox for Enterprise Helpに記載されている指定のいちにルート証明書を配置することらしい(ちゃんと読んでいない)。

証明書の情報

すこし証明書のなかみのを確認

certificate

発行先は自分のPCの自分のアカウントで、発行元のは自分のPCの自分のアカウントのmkcertとのこと。 有効期限は2年3ヶ月(27ヶ月)ですね。Let's Encryptoよりも随分長い。こちらのほうが便利かもしれないですね。

詳細もスクショしようと思いましたが消すのめんどくさくなってきたので、文字情報だけで。

おわりに

今回の方法はmkcertを使うことでlocalhost127.0.0.1)を27ヶ月間更新する手間なくHTTPS化して開発することができます。また、WSLがなくてもWindowsLinuxMacで実行できます。

以前、書いた記事ではFreenomでドメインを取得して、certbotを使ってLet's Encryptoの証明書を作成し、3ヶ月ごとに更新する必要がありました。

今回の記事のほうが更新頻度も少なくて楽。また、環境を他の開発者に共有したり、配布するときにこちらのほうが良さそう(Dockerで配布とかもできる??)なので、こちらの方法に切り替えていこうかなと思っています。

参考文献