PHP・Laravelで作成したアプリをAWSのEC2へデプロイする際に、本番環境では常にHTTPS通信を行うことになると思います。
何も設定しないとHTTP通信になってしまうので、この記事ではLaravelをセキュア(=暗号化)な状態で通信するための設定を記載します。
環境の設定
'env' => env('APP_ENV', '〇〇〇'),
〇〇〇
の箇所について、開発環境の場合(ローカルで開発する際)はlocal
、本番環境の場合(デプロイする際)はproduction
にしてください。
ここを設定することで、開発環境か本番環境のどちらか切り替えることができます。
URLをhttpsにする
AppServiceProvider.phpを下記のように追記してください。
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\URL; //追記
class AppServiceProvider extends ServiceProvider
{
//略
public function boot()
{
// ここから追記
if (config('app.env') === 'production') {
URL::forceScheme('https');
}
// ここまで追記
}
}
これで開発環境の時のURLがhttp、本番環境の時のURLがhttpsになりました。
本番環境において、httpでアクセスされた際にhttpsへリダイレクトさせるための処理
middlewareの作成
次のコマンドを実行してmiddlewareを作成します。RedirectToHttps
の箇所はご自身が作りたいクラス名を記載してください。
$ php artisan make:middleware RedirectToHttps
作成されたRedirectToHttps.php
を下記のように追記してください。
<?php
namespace App\Http\Middleware;
use Closure;
class RedirectToHttps
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// ここから追記
//このhandleメソッドで判別
if (!$this->is_ssl() && config('app.env') === 'production') {
return redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
}
// ここまで追記
return $next($request);
}
// ここから追記
//Webサーバー毎にキーと値で判別
public function is_ssl()
{
if (isset($_SERVER['HTTPS']) === true) { // Apache
return ($_SERVER['HTTPS'] === 'on' or $_SERVER['HTTPS'] === '1');
}
elseif (isset($_SERVER['SSL']) === true) { // IIS
return ($_SERVER['SSL'] === 'on');
}
elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) === true) { // Reverse proxy
return (strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https');
}
elseif (isset($_SERVER['HTTP_X_FORWARDED_PORT']) === true) { // Reverse proxy
return ($_SERVER['HTTP_X_FORWARDED_PORT'] === '443');
}
elseif (isset($_SERVER['SERVER_PORT']) === true) {
return ($_SERVER['SERVER_PORT'] === '443');
}
return false;
}
// ここまで追記
}
Kernel.phpに登録
先程作成したRedirectToHttps.phpの内容を反映させるために、Kernel.phpのprotected $middleware
に追記します。
// 略
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\RedirectToHttps::class, // 追記
];
// 略
補足
全プロキシを信用
全プロキシを信用するために、TrustProxies.phpに*
を追記します。
protected $proxies = '*';
詳細は信用するプロキシの設定を確認してください。
CSSを反映させる
URLがhttpsになると、CSSが適用されません。
asset
をsecure_asset
にすることで反映されます。
app.blade.php
のheaderタグにおいて、CSSを適用している箇所をこのように書き換えると良いと思います。
@if(config('app.env') === 'production')
<link rel="stylesheet" href="{{ secure_asset('css/app.css') }}">
@else
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
@endif
開発環境(http)の時はasset
、本番環境(https)の時はsecure_asset
にすることで、CSSが通常通り反映されます。
AWS側の設定
SSL証明書の作成、ロードバランサー、セキュリティーグループ等の設定が必要になります。
この記事がとてもわかりやすかったので、共有しておきます。
一点補足することがあります。
上記の記事ではロードバランサーの作成において、最後にターゲットの確認をして、Health status
がhealthy
になっています。
しかし、URLをhttpからhttpsへリダイレクトさせると、Health status
がunhealthy
になってしまします。
unhealthy
になっていても通常通り動くので、大した問題ではありません。
ただ、unhealty
が気になる方は、下記の設定を行うことでhealthy
になります。
1.ターゲットグループを選択
2.Health CheckのEditをクリック
3.Advanced health check settingsのSuccess codesに302を追加し、Save changesをクリック
参考記事
Laravelで作ったサービスをSSL化した時にやったことと参考記事一覧
LaravelでURLをHTTPS化させるメモ (Heroku)
https対応したLaravelプロジェクトでassetを使う時の注意点
EC2上のwebサーバをSSL化対応
おわりに
最後まで読んでいただき、ありがとうございます。
間違いがあればご指摘いただけると幸いです。