Laravel 12 域名限制需结合 Route::domain() 路由分组与白名单中间件双重校验:前者按 Host 头分流,后者用 #[Middleware] 属性语法运行时拦截非法域名,同时须正确配置 APP_URL 和 SESSION_DOMAIN。

在 Laravel 12 中,限制路由只允许指定域名访问,核心是结合 Route::domain() 路由分组和自定义中间件完成双重校验:前者按 Host 头分流请求,后者做运行时白名单拦截,确保即使路由被误配或绕过 domain 分组,也能兜底拒绝非法域名。
用 Route::domain() 按域名组织路由
这是 Laravel 原生支持的子域名路由机制,不依赖中间件,但它是结构化隔离的第一步:
- 写法必须用
Route::domain('app.example.com')->group(...)或通配式Route::domain('{sub}.example.com')->where('sub', 'app|admin') - 它只匹配 HTTP 请求头中的
Host字段(含端口),比如app.example.com:8000会被识别为app.example.com:8000,不是app.example.com - 该分组本身不阻止非法域名访问——如果有人把 Host 改成
hacker.com却仍命中了某条通用路由,就会漏掉;所以必须搭配中间件做二次校验
写一个域名白名单中间件
中间件负责真正拦截。Laravel 12 要求使用 PHP 8.2+ 属性语法,并注意 Host 处理细节:
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
- 必须用
php artisan make:middleware RestrictDomains创建,不能手动新建文件 - 在
handle()方法中,用$request->headers->get('host')获取原始 Host,再用explode(':', ...)[0]剔除端口,转小写后比对 - 白名单建议从配置读取,例如
config('app.allowed_hosts', ['app.example.com', 'admin.example.com']),方便不同环境切换 - 不匹配时直接
abort(404)或response('', 403)->header('X-Content-Type-Options', 'nosniff'),避免泄露信息
绑定中间件到域名路由组
中间件要作用于特定分组,而不是全局注册:
- 在
routes/web.php中,把中间件传给middleware()方法:Route::domain('app.example.com')->middleware([RestrictDomains::class])->group(...) - 不要在
app/Http/Kernel.php的$middlewareGroups或$routeMiddleware里注册这个中间件为“全局”或“别名”,除非你明确需要复用 - 若用 PHP 属性语法(Laravel 12 推荐),可在控制器方法上加
#[Middleware(RestrictDomains::class)],但路由组方式更清晰、更易维护
同步检查环境与会话配置
域名限制生效的前提,是整个应用层信任 Host 头,否则中间件判断无意义:
- 确认
.env中APP_URL=https://app.example.com和SESSION_DOMAIN=.example.com(注意开头的点)已设置正确 - Laravel 12 默认启用严格域匹配,
SESSION_DOMAIN若缺失或错误,会导致登录态丢失、CSRF 失败,间接让中间件“看似失效” - 开发时若用
localhost:8000,需把localhost加入白名单,并确保浏览器允许该域名下的 Cookie


















