问题
当我们将 Laravel 专案部署到网路上之后,可能会申请域名和凭证。但是却不能确保使用者必然使用 HTTPS 连线至我们的网站。故想要强制将 HTTP 转为 HTTPS。
解决
概念
为所有 route 绑上 middleware。当有 request 进来的时候,判断是否为 HTTPS,如若不是,则改以 HTTPS 重新导向。
实作
HttpsProtocol.php
在 专案根目录/app/Http/Middleware 里建立 HttpsProtocol.php。档案程式码如下:
<?phpnamespace App\Http\Middleware;use Closure;use Illuminate\Support\Facades\App;class HttpsProtocol { public function handle($request, Closure $next) { if (!$request->secure() && App::environment() === 'production') { return redirect()->secure($request->getRequestUri()); } return $next($request); }}
说明
在 handle() 里,$request->secure() 判断请求是否为 SSL,如果是会回传 true,否则回传 false。
App::environment() 则是去抓 .env 的 APP_ENV 环境变数。只有当 .env 设定为 APP_ENV=production 时会回传 true。
当两个判断皆为真,才会改以 HTTPS 重新导向。所以在本地开发的时候设定 APP_ENV=local 就不会受到影响,而在部署好的专案里只要将变数设定为 APP_ENV=production 即可作用。
以上,已经完成强制重新导向的档案了。接下来要套用它。
Kernel.php
在 专案根目录/app/Http 里修改 Kernel.php。程式码片段如下:
protected $middleware = [ \App\Http\Middleware\TrustProxies::class, \Fruitcake\Cors\HandleCors::class, \App\Http\Middleware\CheckForMaintenanceMode::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \App\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, // 加上这行套用上面写好的 Middleware \App\Http\Middleware\HttpsProtocol::class, ];
说明
以上,则能让所有 route 被访问前都先经过此 middleware 过滤。
完成!
参考网站
https://stackoverflow.com/questions/28402726/laravel-5-redirect-to-https
原文作者在 Laravel 5 上实作。笔者则是在 Laravel 7 上实作,亦可以顺利执行。