Laravel如何按路由分组应用自定义中间件,仅让admin前缀的路由生效?
- 内容介绍
- 文章标签
- 相关推荐
本文共计894个文字,预计阅读时间需要4分钟。
全局中间件($middleware 数组)负责处理所有请求的生命周期,包括 API、静态资源以及健康检查等。
常见错误是图省事,在 app/Http/Kernel.php 里把自定义中间件塞进 $middleware,结果登录页、首页、甚至 /storage/logo.png 都被拦截了。
- 正确位置是
$middlewareGroups['web']或新建分组(如'admin') - 如果中间件只用于后台,建议单独建分组,避免和前台逻辑耦合
- 注册后必须在路由定义中显式调用,不会自动继承
路由分组时用 middleware 键指定中间件名
Laravel 路由分组本身不自动加载中间件,必须手动绑定。只写 prefix('admin') 不会触发你的中间件。
典型写法:
Route::middleware(['admin.auth'])->prefix('admin')->group(function () { Route::get('/dashboard', [AdminController::class, 'index']); Route::get('/users', [AdminController::class, 'list']); });
-
admin.auth是你在app/Http/Kernel.php中注册的中间件别名,不是类名 - 别名必须和
$routeMiddleware数组里的键完全一致,大小写敏感 - 如果中间件需传参(比如权限码),不能在这里写
admin.auth:manage_users—— Laravel 5.5+ 不支持路由闭包里传参,得改用闭包中间件或构造器注入
中间件类里用 $request->route() 判断当前路径是否匹配
有些场景光靠路由分组不够:比如你希望中间件在 /admin 下生效,但又允许 /admin/login 绕过校验。这时候不能只依赖分组,得在中间件内部做细粒度判断。
关键点是别用 $request->url() 或 $request->fullUrl() 做字符串匹配 —— 容易漏掉 query 参数或路由模型绑定后的实际路径。
- 优先用
$request->route()?->getName()或$request->route()?->uri() -
$request->route()?->uri()返回的是定义的路由模式(如admin/dashboard),不含域名和 query,适合做前缀判断 - 示例绕过逻辑:
if ($request->route()?->uri() === 'admin/login') { return $next($request); }
- 注意空指针:一定要加
?->,因为 CLI 命令或某些异常请求可能没有 route 实例
测试时别只刷浏览器,要验证 CLI 和 API 场景
很多人本地测 /admin/dashboard 能跳转就以为 OK,结果上线后 php artisan schedule:run 报错,或者 /api/admin/stats 被意外拦截。
- CLI 请求不走
web中间件组,默认只经过$middleware,如果你把 admin 中间件错放进去,命令行会卡住 - API 路由默认用
api中间件组,和web是隔离的,除非你手动在routes/api.php里加middleware('admin.auth') - 真实部署时 Nginx/Apache 可能重写 URL,导致
$request->route()?->uri()和预期不符,建议日志里 dump 一下实际值
最常被忽略的是中间件在服务提供者里注册了但没清缓存 —— 改完 Kernel.php 后记得运行 php artisan route:clear,否则路由缓存仍按旧配置走。
本文共计894个文字,预计阅读时间需要4分钟。
全局中间件($middleware 数组)负责处理所有请求的生命周期,包括 API、静态资源以及健康检查等。
常见错误是图省事,在 app/Http/Kernel.php 里把自定义中间件塞进 $middleware,结果登录页、首页、甚至 /storage/logo.png 都被拦截了。
- 正确位置是
$middlewareGroups['web']或新建分组(如'admin') - 如果中间件只用于后台,建议单独建分组,避免和前台逻辑耦合
- 注册后必须在路由定义中显式调用,不会自动继承
路由分组时用 middleware 键指定中间件名
Laravel 路由分组本身不自动加载中间件,必须手动绑定。只写 prefix('admin') 不会触发你的中间件。
典型写法:
Route::middleware(['admin.auth'])->prefix('admin')->group(function () { Route::get('/dashboard', [AdminController::class, 'index']); Route::get('/users', [AdminController::class, 'list']); });
-
admin.auth是你在app/Http/Kernel.php中注册的中间件别名,不是类名 - 别名必须和
$routeMiddleware数组里的键完全一致,大小写敏感 - 如果中间件需传参(比如权限码),不能在这里写
admin.auth:manage_users—— Laravel 5.5+ 不支持路由闭包里传参,得改用闭包中间件或构造器注入
中间件类里用 $request->route() 判断当前路径是否匹配
有些场景光靠路由分组不够:比如你希望中间件在 /admin 下生效,但又允许 /admin/login 绕过校验。这时候不能只依赖分组,得在中间件内部做细粒度判断。
关键点是别用 $request->url() 或 $request->fullUrl() 做字符串匹配 —— 容易漏掉 query 参数或路由模型绑定后的实际路径。
- 优先用
$request->route()?->getName()或$request->route()?->uri() -
$request->route()?->uri()返回的是定义的路由模式(如admin/dashboard),不含域名和 query,适合做前缀判断 - 示例绕过逻辑:
if ($request->route()?->uri() === 'admin/login') { return $next($request); }
- 注意空指针:一定要加
?->,因为 CLI 命令或某些异常请求可能没有 route 实例
测试时别只刷浏览器,要验证 CLI 和 API 场景
很多人本地测 /admin/dashboard 能跳转就以为 OK,结果上线后 php artisan schedule:run 报错,或者 /api/admin/stats 被意外拦截。
- CLI 请求不走
web中间件组,默认只经过$middleware,如果你把 admin 中间件错放进去,命令行会卡住 - API 路由默认用
api中间件组,和web是隔离的,除非你手动在routes/api.php里加middleware('admin.auth') - 真实部署时 Nginx/Apache 可能重写 URL,导致
$request->route()?->uri()和预期不符,建议日志里 dump 一下实际值
最常被忽略的是中间件在服务提供者里注册了但没清缓存 —— 改完 Kernel.php 后记得运行 php artisan route:clear,否则路由缓存仍按旧配置走。

