
gates 用于授权(判断“用户能否执行某操作”),middleware 用于请求过滤(拦截并处理 http 请求,如认证、日志、cors 等);二者职责分离、互不包含,可协同使用但无嵌套关系。
在 Laravel 中,Gate 和 Middleware 是两个独立且正交的概念,常被初学者混淆,尤其当两者都涉及“用户访问控制”时。关键在于:它们解决的是不同层面的问题——Middleware 处理请求生命周期,Gate 处理业务逻辑授权。
✅ Middleware:请求管道的“守门员”
Middleware 运行在 HTTP 请求进入应用后的早期阶段(或响应返回前),对整个请求-响应周期进行干预。它不关心具体业务动作,只关注请求本身是否合规。例如:
- auth 中间件检查请求是否携带有效认证凭证(如 session 或 token),若未登录则重定向至 /login;
- verified 中间件确保用户邮箱已验证;
- 自定义中间件可记录请求日志、限制 API 频率、强制 HTTPS 等。
// app/Http/Middleware/CheckAge.php
public function handle(Request $request, Closure $next)
{
if ($request->age < 18) {
return redirect('adults-only');
}
return $next($request);
}⚠️ 注意:Middleware 不具备用户行为细粒度判断能力——它无法回答“当前用户能否删除这篇博客?”这类问题,因为它通常不加载完整用户模型或业务上下文。
✅ Gate(及 Policy):业务授权的“裁判员”
Gate 是 Laravel 的授权机制,专为“某用户是否被允许执行某操作”而设计。它基于用户实例、资源和动作三元组进行动态判断,支持闭包定义或 Policy 类封装:
// 定义 Gate(app/Providers/AuthServiceProvider.php)
Gate::define('delete-post', function (User $user, Post $post) {
return $user->id === $post->user_id || $user->role === 'admin';
});
// 控制器中使用
if (Gate::allows('delete-post', $post)) {
$post->delete();
} else {
abort(403);
}或配合 Policy 实现更清晰的授权逻辑:
// 调用策略方法(自动解析)
$this->authorize('delete', $post); // 触发 PostPolicy@delete()✅ Gate 的优势在于:支持资源绑定、依赖注入、策略复用,并天然适配 Blade 指令(@can('update', $post))和 JSON API 响应。
❌ 它们不是包含关系
Middleware 不包含 Gate,Gate 也不属于 Middleware。你不能在中间件里“调用 Gate”来实现登录跳转——因为未认证用户根本拿不到 $user 实例,Gate::allows() 将抛出异常或返回 false,但这并非其设计目的。正确的做法是:
- ✅ 用 auth 中间件保障路由级访问(如 middleware('auth'));
- ✅ 在控制器或服务层用 Gate::allows() 或 $this->authorize() 执行操作级授权。
? 协同工作示例
一个典型的博客编辑页可能这样组合使用:
// routes/web.php
Route::get('/posts/{post}/edit', [PostController::class, 'edit'])
->middleware('auth') // 第一层:必须登录
->can('update', 'post'); // ⚠️ 注意:这是 Laravel 9+ 的「授权中间件」语法(底层仍调用 Gate)
// PostController.php
public function update(Request $request, Post $post)
{
$this->authorize('update', $post); // 第二层:校验该用户能否更新此文章
$post->update($request->validated());
}? 提示:->can('update', 'post') 是 Laravel 提供的便捷授权中间件语法,它内部调用 Gate,但本质仍是 Middleware 层的快捷注册方式——它并未让 Gate “嵌入” Middleware,而是桥接二者。
总结
| 维度 | Middleware | Gate / Policy |
|---|---|---|
| 核心目标 | 过滤/修改请求或响应 | 判断用户是否有权执行特定操作 |
| 执行时机 | 请求进入/响应发出时(全局) | 业务逻辑中按需调用(局部) |
| 依赖上下文 | Request、Response、Closure | User 实例、资源模型、动作字符串 |
| 典型用途 | 认证、日志、CORS、CSRF | 权限控制、角色判断、多租户隔离 |
| 是否可替代 | ❌ 不能替代 Gate 的细粒度授权 | ❌ 不能替代 Middleware 的请求拦截 |
理解这一区分,是构建安全、可维护 Laravel 应用的关键基础。










