すべての記事
HTTPSmkcertlocal developmentlocalhost tunneling

localhost の HTTPS:mkcert と トンネルを正直に比較

ツールは 2 つ、問題は 1 つ:開発サーバーが HTTPS で到達可能である必要があります。mkcert はローカルで信頼される TLS 証明書を与え、https://localhost:3000 がそのまま動きます。トンネルは本物の CA の本物の証明書に裏打ちされた公開 HTTPS URL を与えます。両者は競合相手ではなく——別の問題を解きます——が、人々はずっと競合のように扱います。

短い答え

  • 自分のマシンの、自分のブラウザーだけに HTTPS が要る? mkcert を使う。
  • 外部サービス(Stripe、GitHub、Auth0、スマホ)が開発サーバーに到達する必要がある? トンネルを使う。
  • 両方? 両方動かす。ぶつかりません。

これが記事の全部、3 つの箇条書きです。残りは理由だけ。

mkcert:30 秒でローカル信頼の証明書

mkcert は OS の信頼ストアにローカル認証局をインストールし、そこから証明書を発行します。CA が信頼されているので、ブラウザーは証明書を信頼済みと見ます。この接続ではプライバシーが保護されませんの警告も、--ignore-certificate-errors フラグも、自作の自己署名証明書もなし。

# マシンごとに 1 回
mkcert -install

# プロジェクトごとに 1 回
mkcert localhost 127.0.0.1

# これで localhost.pem と localhost-key.pem ができる

開発サーバー(Vite、Next.js、Express、Django runserver_plus はすべて TLS 引数をサポート)に組み込めば、本物の証明書で https://localhost:3000 が手に入ります。

落とし穴:その CA を信頼するのはあなたのマシンだけ。同僚のブラウザーは警告します。スマホは CA ルートを手動でインストールしない限り信頼しません。

トンネル:本物の HTTPS、本物の公開 URL

localhost トンネルは公開 HTTPS URL からローカルポートへトラフィックを転送します。証明書は本物の CA(Let's Encrypt など)が発行し、あらゆるデバイスのあらゆるブラウザーが信頼します。

npx portpreview 3000

トンネルはクラウドゲートウェイで TLS 終端を処理します。ローカルサーバーは素の HTTP のままで構いません——公開 URL が HTTPS で、外部サービスが触れる面はそこです。

並べて比較

ニーズmkcertトンネル
ローカルブラウザーでの HTTPSはいはい(公開 URL 経由)
ブラウザーでの service worker / secure cookie テストはいはい
外部プロバイダーが到達できるいいえはい
手元のスマホが到達できるいいえ(CA を入れなければ)はい
OAuth プロバイダーが URL を受け入れる時々(Google:はい、多くは:いいえ)はい
Stripe / GitHub / Twilio が Webhook できるいいえはい
セットアップ時間マシンごと 30 秒セッションごと 1 コマンド
オフラインで動くはいいいえ
機内モードでも生きるはいいいえ

みんなが間違えるところ

Webhook テストに mkcert を使おうとする

Stripe はあなたのマシンのローカル CA を信頼できません。ブラウザーで証明書がどれだけ信頼済みに見えても——Stripe は別ネットワークにいます。公開インターネットからの受信トラフィックにはトンネルが必要です。

1 人ブラウザーだけの HTTPS にトンネルを使う

自分のブラウザーで service worker を動かしたい、secure cookie を設定したいだけなら、mkcert のほうが速くオフラインでも動きます。証明書ファイルで済むことにトンネルセッションを浪費しないこと。

1 つのツールを選んでもう片方のユースケースを無理に通す

両方動かすので大丈夫。私たちのセットアップの大半は、日々のブラウザー側作業に mkcert、Webhook や OAuth コールバックのテスト時にトンネルを使います。package.json で衝突なく同居します。

Caddy や nginx は?

はい、開発サーバーの前に自動 HTTPS の Caddy を置けますし、それも動きます——本質的に「余計な手順とリバースプロキシつきの mkcert」です。多くのローカル開発では mkcert のほうが簡単。複数のローカルサービスを伴う凝ったルーティングには Caddy が活きます。

私たちの実際のセットアップ

私たちが作業するあるリポジトリでは、localhost 側 HTTPS 用に dev スクリプトに mkcert、誰かが Webhook やモバイルテストを要るときに portpreview を走らせる別の tunnel npm スクリプトがあります。トンネル URL は env 変数で渡され、OAuth リダイレクト URI を簡単に差し替えられます。配線に 20 分、それ以降ローカル TLS を考えたことはありません。

OAuth 向けのトンネル設定は OAuth コールバックをローカルでテストする方法を参照。同僚やデザイナーとプレビューを共有するなら ローカル開発サーバーの共有。このセットアップのトンネル側は PortPreview のウェイトリストへ。

よくある質問

ローカル HTTPS には mkcert とトンネルのどちらを使うべき?
用途が違うので両方です。mkcert は自分のブラウザーに localhost で信頼される証明書を与え、オフラインで動きます。トンネルは外部サービスや他デバイスが到達できる公開 HTTPS URL を与えます。衝突せず、多くのチームは両方使います。
mkcert は Stripe や GitHub からの Webhook テストを扱えますか?
いいえ。mkcert の証明書は CA をインストールしたマシンだけで信頼されます。外部の Webhook プロバイダーは、ローカルブラウザーで証明書がどれだけ信頼済みでも localhost に到達できません。受信する公開トラフィックにはトンネルを使ってください。
mkcert は OAuth の localhost コールバックに使えますか?
一部のプロバイダー(Google、Auth0 の特定の開発ティア)は開発用に HTTP か HTTPS の localhost を受け入れます。多くは受け入れません。mkcert は受け入れる側に HTTPS を提供しますが、厳格な側には公開 HTTPS URL のトンネルが必要です。