Laravel 11 中拦截非法域名需在中间件 handle() 中调用 $request->getHost() 与白名单严格比对,不匹配则返回 403;注意 Host 可伪造,仅用于基础分流,且中间件须注册在 $middlewareGroups['api'] 或 ['web'] 中靠前位置,避免放入全局 $middleware。

在 Laravel 11 中,用中间件拦截非法域名,核心是通过 $request->getHost() 获取请求的 Host 头,并与白名单比对。但要注意:Host 值可被客户端伪造,不能用于安全认证(如权限判断),仅适合做基础路由分流或拒绝明显异常的请求。
获取并校验 Host 值
在自定义中间件的 handle() 方法中直接调用 $request->getHost(),它返回的是 HTTP 请求头中的 Host 字段(不含端口,如 api.example.com)。不建议用 $_SERVER['HTTP_HOST'] 或解析 URL,因为 Laravel 的 getHost() 已处理了标准化和代理兼容逻辑。
- 先定义合法域名列表,例如:
$allowedHosts = ['api.yourapp.com', 'staging-api.yourapp.com'];</li> <li>用 <code>in_array($request->getHost(), $allowedHosts, true)
严格比对 - 若不匹配,直接终止请求:
return response('Forbidden', 403);
注意 Host 可能带端口,需清洗
开发环境下(如 localhost:8000)getHost() 会返回带端口的字符串。若白名单只写 localhost,比对会失败。解决方式有两种:
- 统一用
parse_url($request->url(), PHP_URL_HOST)提取纯域名(自动剥离端口) - 或在比对前截断端口:
$host = explode(':', $request->getHost())[0];
推荐前者,更健壮。
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
必须放在路由匹配之后、其他业务中间件之前
Host 校验中间件要注册在 $middlewareGroups['api'] 或 ['web'] 中,且位置靠前——确保它在 Session、Auth 等中间件之前执行,避免无效请求消耗后续资源。不要放进全局 $middleware 数组,否则静态资源、健康检查等也会被拦截。
- 正确示例(
app/Http/Kernel.php):'api' => [ \App\Http\Middleware\VerifyHost::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ... ] - 错误做法:加到
$middleware顶层,导致所有请求(包括/vendor、/storage)都被 Host 检查
配合 Nginx 做更早拦截(生产环境强烈建议)
中间件属于 PHP 层,请求已进入应用。真正高效的域名过滤应在 Web 服务器层完成。Nginx 可直接按 $host 变量 return 444(关闭连接)或 403:
if ($host !~ ^(api\.yourapp\.com|staging\-api\.yourapp\.com)$) { return 403; }- 或用
map指令预定义变量,性能更高
这样既减轻 PHP 负担,又防止恶意 Host 头触发 Laravel 自动加载和日志记录。

















