Laravel + vue.jsで作成したポートフォリオをデプロイするために初めてAWSを利用したところ様々な問題にぶつかり、解決に時間を要しました。
- 発生した問題
- JSファイルやCSSファイルが正しく読み込まれない問題 (★ 本記事)
- ブラウザを問わず、数分毎にHTTPとHTTPSが切り替わってしまう問題
備忘録も兼ねて、前後編という形でここに記していきます。
※ Laravel 6.20.26
【前提】AWSの構成
初めてAWSを利用してインフラ構築を行ったので、十分な理解ができているとは言えないと思います。
ハンズオン形式で学習しつつ手探りで作った部分がありますので、「もっとここはこうしたら良いよ」といったことがあればご指摘いただけると幸いです。
LaravelプロジェクトはWEBサーバに設置。
ユーザーからの通信はHTTPS通信のみ受け付け、そのリクエストの内容によりALBがWEBサーバかメールサーバかに分岐します。
ALBから先はHTTP通信でやりとりを行う、という構成です。
JSファイルやCSSファイルが正しく読み込まれない問題
JSファイルもCSSファイルも読み込まれず、テキストだけの寂しい画面が現れました。一体どういうことなのでしょう。
早速確認してみます。すると...
JSファイルとCSSファイルを読み込む際に、パスがhttps://~~
ではなくhttp://~~
になってしまっています。
パスが間違っているのですから当然読み込まれません。
該当箇所のHTMLは以下の通り。
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
どうやらヘルパー関数asset()
がリンクをhttpで生成してしまっていることが原因のようです。
asser()がhttpsリンクを生成しない理由
TLS/SSL証明を行うロードバランサの裏でアプリケーションが実行されている場合、アプリケーションがときどきHTTPSリンクを生成しないことに、気づくでしょう。典型的な理由は、トラフィックがロードバランサにより80番ポートへフォワーディングされるため、セキュアなリンクを生成すべきだと判断できないからです。
とのこと。
LaravelプロジェクトはALBの先にあるWebサーバに設置しているので、ユーザーがhttpsでアクセスしてきてもプロジェクト側から見ればhttpでアクセスされてきた扱いになります。
Laravelのヘルパー関数asset()
やurl()
などは、httpアクセスされてきたことを受けて、
「じゃあ生成するリンクもhttpにしよう!」
と判断してしまうわけですね。
一応asset()
ではなくsecure_asset()
を使えばhttpsに変換してくれるので一応は解決しますが、ローカル環境ではhttpですし、いちいち置き換えていくのは面倒です。
TrustProxiesの編集
そこで、app/Http/Middleware/TrustProxies.php
を編集していきましょう。
ALBに紐付けたサブネットのIPアドレスを記述していきます。
<?php
namespace App\Http\Middleware;
use Fideloper\Proxy\TrustProxies as Middleware;
use Illuminate\Http\Request;
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array|string
*/
// 以下に追記!
protected $proxies = [
// ここにALBに紐づけたIPアドレスを記述します
'192.168.1.0/24',
'192.168.2.0/24',
];
// 以下略
}
さて、追記した結果どうなったでしょうか?
CSSが無事に読み込まれ、JSファイルも無事に動いているようです!
ちゃんとhttpsでリンク生成されていますね!
これで問題は無事に解決...するほど甘くはありませんでした。