58
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

https対応したLaravelプロジェクトでassetを使う時の注意点

Laravel5.5製のWebアプリケーションをhttps化させた時に遭遇した問題とその解決方法について書きます。

読み込みファイルのパスのプロトコルが変わらない問題

Laravelにはviewでcssやjsを読み込む際にフルパスを記述するためのメソッドが用意されています。

たとえばcssを読み込みたい時は

<link href="{{ asset('css/your_app.css') }}" rel="stylesheet">

jsを読み込みたい時は

<script src="{{ asset('js/your_app.js') }}"></script>

と書くことができます。
これらは実際にローカルでページにアクセスすると

# css
http://localhost/css/your_app.css
# js
http://localhost/js/your_app.js

のように展開されます。
headerの情報を元に参照hostを判断して動的に生成してくれます。

しかし、なぜかプロトコルのところはアクセス元の情報に沿わずにhttpとして展開されてしまいます。

https://your_domain にアクセスしたら

# css
http://your_domain/css/your_app.css
# js
http://your_domain/js/your_app.js

と展開されます。
これだとcssとjsのロードエラーがフロントで発生するため、何かしら回避策が必要です。

回避方法

そこで、https通信のときだけassetで返されるURLをhttpsにすることにしました。

まずhttpsかどうかの判定にはリクエストオブジェクトから呼び出せるisSecureというメソッドを使って判定しました。
これは単純にアクセス元のプロトコルだけでなく、headerのX_FORWARDED_PROTOも見てくれるので、AWSでロードバランサーを介してhttps化している場合でも対応が可能です。

ただし、ロードバランサー経由の場合は追加で

TrustProxies.php
protected $proxies = '**';

と記述する必要があります。
Laravelはデフォルトではプロキシー経由のリクエストにおけるhttpsを許容していないらしく、TrustProxies.phpに追記する必要があります。AWSのロードバランサーはipアドレスが動的に変わるためワイルドカードを指定します。
参考: https://readouble.com/laravel/5.5/ja/requests.html#configuring-trusted-proxies

そして、URL生成でhttpsを強制するための方法としてforceSchemeというメソッドが用意されているので、これを使いました。
https://laravel.com/api/5.5/Illuminate/Routing/UrlGenerator.html#method_forceScheme

AppServiceProviderのboot()の中に下記の記述をすることで対応できます。

AppServiceProvide.php
    public function boot()
    {
        if (request()->isSecure()) {
            \URL::forceScheme('https');
        }
    }

これでhttpでもhttpsでも大丈夫になりました。

最後に

調べていると本番環境は常にhttpsにするって方法がちらほら出てきましたが、ステージング環境とか必要箇所が増えるたびに環境変数の対応箇所が増えてきてしまうので、単純に通信のプロトコルをみて判断できる実装のほうが良いのではないかなと思いました。

また、こういうエラーはローカルでは検証しづらく、httpsな環境にあげたときにしか気づけ無いので、httpsなステージング環境は必要ですね。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
58
Help us understand the problem. What are the problem?