Laravel 13 中推荐使用路由级域名限制(Route::domain()),因其原生支持、可阻止路由匹配、支持参数提取;中间件级仅为辅助手段,存在资源消耗、无法拦截静态资源等缺陷。

Laravel 13 中实现域名限制(如仅允许特定域名访问某组路由)主要有两种层级方式:路由级和中间件级,但推荐且真正有效的是路由级限制,中间件级属于补救或辅助手段,存在明显局限。
✅ 路由级域名限制(原生支持、精准可靠)
Laravel 原生通过 Route::domain() 提供声明式域名匹配,这是唯一能真正拦截请求在路由匹配阶段的方式。
- 它基于 HTTP 请求头中的
Host字段做正则/字符串匹配,匹配失败则完全不进入后续流程(包括中间件和控制器) - 必须在
RouteServiceProvider::mapWebRoutes()阶段注册(即写在routes/web.php中,且不能包裹在其他分组里误用) - 支持通配符和参数提取,例如:
Route::domain('{tenant}.example.com')->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index']);
});
- ⚠️ 关键顺序:子域名路由必须先于根域名路由注册。否则
company.example.com/可能被Route::get('/')意外捕获。
⚠️ 中间件级域名限制(可用但有缺陷)
你可以在中间件中手动检查 $request->getHost() 或 $request->header('Host'),然后拒绝请求:
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
public function handle($request, Closure $next)
{
$host = $request->getHost();
if (!in_array($host, ['app.example.com', 'admin.example.com'])) {
abort(403, 'Domain not allowed');
}
return $next($request);
}
但这种方式存在几个硬伤:
- 请求已进入 Laravel 生命周期,Session、CSRF、中间件链已部分执行,资源已被消耗
- 无法阻止对静态资源(如
/favicon.ico)或未定义路由的无效访问(它们仍会走到这个中间件) - 若放在路由分组中,需确保该中间件在所有其他中间件之前注册,否则可能被前置中间件(如
VerifyCsrfToken)提前终止 - 无法替代
Route::domain()的语义表达力,比如无法自动注入{tenant}参数
? 对比小结
| 方式 | 是否原生支持 | 是否可阻止路由匹配 | 是否支持参数提取 | 是否推荐用于生产 |
|---|---|---|---|---|
Route::domain() |
是 | 是(完全跳过) | 是(如 {tenant}) |
✅ 强烈推荐 |
| 自定义中间件检查 Host | 否(需手写) | 否(已进路由层) | 否(需自行解析) | ❌ 仅作兜底或日志审计 |
路由级限制是 Laravel 处理多租户、白名单域名、环境隔离等场景的标准实践。中间件级检查更适合做运行时动态策略(如结合数据库查域名黑名单),而不是基础访问控制。










