必须将后台中间件注册到$middlewareGroups而非$middleware,否则会无差别拦截/storage、/health、首页等所有请求;正确做法是新增admin中间件组并确保路由显式调用middleware('admin')。

必须把后台中间件注册到 $middlewareGroups,塞进 $middleware 会导致 /storage、/health、首页等所有请求被拦截,这不是配置问题,是根本用错了位置。
为什么不能往 $middleware 里加后台中间件
全局中间件数组 $middleware 在 app/Http/Kernel.php 里,它对每个 HTTP 请求无差别执行。哪怕你只希望 /admin 路由走权限校验,一旦把 AdminAuthMiddleware::class 塞进去:
- 网站首页
/会跳登录页 -
/storage/app/public/logo.png返回 401 -
/api/health被拒绝,K8s 探针失败
这不是“漏配 session”或“CSRF 没关”,是设计意图完全错位。
正确注册方式:加到 $middlewareGroups['admin']
打开 app/Http/Kernel.php,在 $middlewareGroups 数组里新增一个键值对:
protected $middlewareGroups = [
'web' => [/* ... */],
'api' => [/* ... */],
'admin' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\AdminAuthMiddleware::class,
\App\Http\Middleware\CheckAdminRoleMiddleware::class,
],
];注意几点:
- 别漏掉基础中间件(如
StartSession::class),否则session()在 admin 路由里不可用 - 顺序很重要:
AdminAuthMiddleware应该在SubstituteBindings之后,确保路由参数已解析 - 别用
auth别名——那是web组的,admin组要自己维护完整链
路由分组时必须显式调用 middleware('admin')
注册完不等于自动生效。你在 routes/web.php 中必须这样写:
Route::middleware('admin')->prefix('admin')->group(function() {
Route::get('/dashboard', [AdminController::class, 'index']);
Route::get('/users', [AdminController::class, 'list']);
});常见错误:
- 只写
->prefix('admin'),不写->middleware('admin')→ 中间件完全不触发 - 误用旧式数组写法:
Route::group(['middleware' => 'admin'], ...)→ Laravel 5.3+ 已弃用 - 在
php artisan route:list输出里看不到admin出现在 Middleware 列 → 说明没注册成功或拼写错误
绕过逻辑得在中间件内部做,不能只靠路由分组
有些场景光靠分组不够:比如你希望中间件在 /admin 下生效,但又允许 /admin/login 绕过校验。这时候不能只依赖分组,得在中间件类的 handle 方法里判断:
if ($request->route()?->uri() === 'admin/login') {
return $next($request);
}关键点:
- 别用
$request->url()或$request->fullUrl()做字符串匹配 —— 容易漏掉 query 参数或路由模型绑定后的实际路径 - 优先用
$request->route()?->uri(),它返回的是定义的路由模式(如admin/dashboard),不含域名和 query - 如果
$request->route()是 null(比如静态资源请求),?->可避免报错
最常被忽略的是:中间件组内不能放带参中间件(如 throttle:60,1),这类必须单独绑定到具体路由上;还有,自定义中间件类路径写错、命名空间漏掉 \App\Http\Middleware\ 前缀,都会导致 Class not found 错误。


















