😸

AWSでのMixed Contentエラー対策のためTrustProxiesミドルウェアを設定する

2024/06/09に公開

はじめに

AWSでのLaravelデプロイ時にSSL化を行ったところ画面に表示されずMixed Contentエラーとなった。このための対策としてTrustProxiesミドルウェアの設定が必要であったが、Laravel11からやり方が新しいやり方に変わったため情報があまりなく苦労した。そこでブログに記録を残しておくことにした。

開発環境

Amazon Linux 2
Apache 2.4
MySQL 8.0
Laravel 11
php 8.2
vite 5.2

AWSでの使用サービス

EC2, RDS, Route53, ARB(アプリケーションロードバランサー)

エラー状況

  • ARB(アプリケーションロードバランサー)を使用してSSL化したところ画面が白い状態になった
  • HTMLの情報はきている
  • コンソールに以下のエラーメッセージあり

Mixed Content: The page at '<URL>' was loaded over HTTPS, but requested an insecure stylesheet '<URL>'. This request has been blocked; the content must be served over HTTPS.

原因

Mixied Contentsが起こっている原因は公式に記載があり、以下の通りです。

TLS/SSL証明書を末端とするロードバランサーの背後でアプリケーションを実行している場合、urlヘルパを使用するとアプリケーションがHTTPSリンクを生成しないことがあります。通常、これは、アプリケーションがポート80でロードバランサーからトラフィックを転送していて、安全なリンクを生成する必要があることを認識していないためです。

対処法

公式ドキュメントの記載がある通り2つの処理が必要

  • Laravelアプリケーションが用意しているIlluminate\Http\Middleware\TrustProxiesミドルウェアを有効にする
  • すべてのプロキシを信頼する設定を行う

以下、公式ドキュメントの記載を抜粋

これを解決するには、Laravelアプリケーションが用意しているIlluminate\Http\Middleware\TrustProxiesミドルウェアを有効にして、アプリケーションが信頼するロードバランサーやプロキシを手早くカスタマイズしてください。信頼するプロキシは、アプリケーションのbootstrap/app.phpファイルでtrustProxiesミドルウェアメソッドを使用し指定します。

Amazon AWSまたは別の「クラウド」ロードバランサープロバイダを使用している場合、実際のバランサーのIPアドレスがわからない場合があります。この場合、*を使用してすべてのプロキシを信頼できます。

->withMiddleware(function (Middleware $middleware) {
    $middleware->trustProxies(at: '*');
})

公式ドキュメントへのリンク
https://readouble.com/laravel/11.x/ja/requests.html#configuring-trusted-proxies

解決策

bootstrap/app.phpに以下のコードを記載したところ解決。
「//追加」の記載がある行が今回追加したコードです。

<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Http\Middleware\TrustProxies; // 追加


return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__ . '/../routes/web.php',
        commands: __DIR__ . '/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->web(append: [
            \App\Http\Middleware\HandleInertiaRequests::class,
            \Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets::class, 
             TrustProxies::class, // 追加

        ]);
        $middleware->trustProxies(at: '*'); // 追加
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

useステートメントの役割
use Illuminate\Http\Middleware\TrustProxies; // 追加

このステートメントは、Illuminate\Http\Middleware\TrustProxiesクラスを現在のファイルにインポートします。これにより、このクラスをファイル内で直接使用することができます。

ミドルウェアの追加
TrustProxies::class, // 追加

ミドルウェアをアプリケーションのミドルウェアスタックに追加するコード。これにより、HTTPリクエストが処理される際に、TrustProxiesミドルウェアが適用されるようになります。

ミドルウェアスタックに追加されたTrustProxieはプロキシ設定に従ってすべてのプロキシ設定を信頼します。

つまりミドルウェアの設定によりこういう流れになります。
TrustProxiesミドルウェアが適用=すべてのプロキシ設定を受け入れる

HTTPリクエストが処理される

プロキシ設定
$middleware->trustProxies(at: '*'); // 追加

AWSでは実際のバランサーのIPアドレスがわかりません。この場合、*を使用してすべてのプロキシを信頼する設定を行います。

参考にした記事

https://zenn.dev/kiwiengineer/articles/61eb648b6b6d68

Discussion