ローカル開発環境を独自ドメインでSSL化
改善前
私 (Technote) が先月から開発に携わっているオンライン家庭教師マナリンクの開発環境は Docker Compose で簡単に立ち上がるようになっています。
開発環境構築を行った当時の全体的な構成は以下のような感じでした。
クライアントは Nuxt で http://localhost:8000
API は Laravel で https://localhost
です。
ログインできない問題
Docker Compose と Nuxt の立ち上げが完了し、トップページが表示されて一安心。
開発初日ということで全体感を把握するためいろいろなページを回遊していたところ README に書いてあるアカウントでログイン出来ないことに気づきました。
Chrome の DevTools で Console を見てみると net::ERR_CERT_INVALID
というメッセージ
試しに直接ブラウザから https://localhost
にアクセスしても NET::ERR_CERT_INVALID
APIサーバの https化に https-portal というhttpsサーバを使用していましたが、
ローカルではオレオレ証明書しか使用できないことが原因でした。
chrome://flags
から無効な証明書を許可して対応しているとのことだったので設定を変更
これでようやくログインできるようになりました。
ログインクッキーが保存されない
と思ったのも束の間、今度はリロードするとログアウトしてしまうことが判明
DevTools でログイン時のレスポンスを確認すると後ろの方に小さな警告マークが。
マウスを合わせると原因が表示されました。
This Set-Cookie was blocked because it had the "SameSite=Lax" attribute but came from a cross-site response which was not the response to a top-level navigation.
- Scheme と Port が異なるため CrossSite
- Cookie の SameSite が Lax で Post 送信
が原因なようです。
SameSite by default cookies
を Disabled
にすることでようやくちゃんとログインできるようになりました。
問題点
- セキュリティ上の安全性が低くなる設定をしないと開発できないこと
- 環境構築の手順に前述の設定変更方法も加える必要があり手順が割と増えること
- フロントのURLとAPIのURLが本番環境のそれと大きく異なること
などが問題だと感じたので対応しました。
改善したこと
- Nginx の手前にあった https-portal をやめ、mkcert で作った証明書を使用してNginxのSSLリバースプロキシを配置
- 最初はもともとあった Nginx でSSL化しようと考えましたが、本番ですでに使っていたので触らないようにしました。
-
http://localhost:8000
で動いている Nuxt もhost.docker.internal
を使用してSSL化
変更後の構成は以下のような感じになりました。
クライアントは https://localhost-manalink.jp
API は https://api.localhost-manalink.jp
これは本番サイトに近いURLになりました。
https://manalink.jp
https://api.manalink.jp
他にも Makefile で諸々のコマンドを定義していたので
- hosts への書き込み
- mkcert のインストール
- mkcert コマンドの実行
のSSLの設定用のコマンドをまとめて make ssl
コマンドだけで完了するようにしました。
init:
docker-compose up -d --build
docker-compose exec php-fpm cp .env.local .env
docker-compose exec php-fpm php artisan key:generate
docker-compose exec php-fpm chmod -R 777 storage bootstrap/cache
@make fresh
@make ssl
ifeq ($(shell uname), Darwin)
ssl:
# 以下割愛
また、以上の設定により、新規の開発者は make init
コマンドのみでSSL含めたDocker環境のセットアップが完了します。
躓いたこと
README をちゃんと読んでいなかっので、最初は mkcert で作成した鍵を共有してしまえばmkcertのインストール自体必要ないのではないかと思いました。
しかし mkcert はローカルに認証局を用意してローカル用の証明書を生成するため、それぞれのPCで mkcert をインストールし証明書を生成する必要があります。
Warning: the rootCA-key.pem file that mkcert automatically generates gives complete power to intercept secure requests from your machine. Do not share it.
オンライン家庭教師マナリンクを運営するスタートアップNoSchoolのテックブログです。 manalink.jp/ 創業以来年次200%前後で売上成長しつつ、技術面・組織面での課題に日々向き合っています。 カジュアル面談はこちら! forms.gle/fGAk3vDqKv4Dg2MN7
Discussion