Laravel API项目如何根据SSL有效期实现HTTP动态跳转HTTPS
Laravel 条件HTTPS重定向实现方案
核心逻辑是在HTTP重定向HTTPS的规则前增加SSL证书有效性校验,仅当证书未过期时触发重定向,否则保留HTTP访问。
步骤1:生成自定义中间件
在项目根目录执行Artisan命令创建中间件:php artisan make:middleware ConditionalHttpsRedirect
步骤2:编写中间件逻辑
打开 app/Http/Middleware/ConditionalHttpsRedirect.php 文件,写入如下代码:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Cache; class ConditionalHttpsRedirect { public function handle(Request $request, Closure $next) { // 已为HTTPS请求直接放行 if ($request->secure()) { return $next($request); } $domain = $request->getHost(); $cacheKey = "ssl_cert_valid_{$domain}"; // 从缓存读取证书校验结果,避免每次请求都校验,默认缓存24小时 $certValid = Cache::remember($cacheKey, 86400, function () use ($domain) { $context = stream_context_create([ "ssl" => [ "capture_peer_cert" => true, "verify_peer" => false, "verify_peer_name" => false, ] ]); $socket = @stream_socket_client("ssl://{$domain}:443", $errno, $errstr, 3, STREAM_CLIENT_CONNECT, $context); if (!$socket) { return false; } $cert = stream_context_get_params($socket)["options"]["ssl"]["peer_certificate"]; $certInfo = openssl_x509_parse($cert); fclose($socket); // 校验证书有效期 return $certInfo && time() < $certInfo["validTo_time_t"]; }); // 证书有效则重定向到HTTPS if ($certValid) { return redirect()->secure($request->getRequestUri(), 301); } // 证书无效则继续走HTTP return $next($request); } }
步骤3:注册中间件
打开 app/Http/Kernel.php 文件,将中间件添加到全局中间件数组的最顶部,确保优先执行:
protected $middleware = [ \App\Http\Middleware\ConditionalHttpsRedirect::class, // 其他原有中间件... ];
注意事项
- 如果项目使用了反向代理(Nginx、CDN等),需要先配置Laravel可信代理,确保框架能正确识别原始请求的协议,否则会出现重定向循环。
- 内网环境无法公网访问域名的场景,可以修改证书校验逻辑,直接读取服务器本地存放的证书文件解析有效期即可。
- 证书更新后可以执行
php artisan cache:forget ssl_cert_valid_你的域名清空缓存,触发重新校验。
内容的提问来源于stack exchange,提问作者Ruturajsinh
相关产品推荐
相关产品推荐

