Laravel中间件负责请求入口控制,如登录校验、角色拦截;Policy策略专注模型实例的细粒度授权,如编辑某篇文章。二者分层协作:中间件守大门,Policy管抽屉。

Laravel中间件和Policy策略授权解决的是不同层面的访问控制问题:中间件管“能不能进这扇门”,Policy管“进门后能不能动这个东西”。
中间件侧重请求入口控制
中间件在HTTP请求到达控制器之前执行,属于请求生命周期的前置过滤器。它不关心具体模型或业务逻辑,只判断当前请求是否符合预设条件。
- 适合做登录校验、角色拦截(如
auth、role:admin)、CSRF验证、维护模式检查等全局性判断 - 可注册为全局中间件(所有请求都走)、路由中间件(仅某组路由)或控制器中间件(仅某个控制器)
- 权限判断通常基于用户状态(是否登录、是否有某角色),不涉及具体数据实例,比如
if (!$user || !$user->isEditor()) { abort(403); }
Policy策略专注模型资源操作
Policy是围绕Eloquent模型设计的授权类,把“谁能在什么条件下对哪个数据做哪种操作”封装成清晰的方法,比如view(User $user, Post $post)。
- 必须配合具体模型实例使用,强调“资源上下文”,例如编辑某篇文章、删除某个评论
- 方法签名固定(当前用户 + 目标模型),逻辑聚焦在数据所有权、状态、关系等细节上,比如
return $user->id === $post->user_id; - 调用方式灵活:可在控制器中用
$this->authorize('update', $post),也可在Blade模板中用@can('delete', $post)
它们经常一起配合使用
典型流程是:先用中间件确保用户已登录且具备基本身份(比如auth中间件),再在控制器里用Policy检查具体操作是否被允许。两者不是替代关系,而是分层协作——中间件守大门,Policy管抽屉。
比如管理后台首页路由可能加middleware(['auth', 'role:admin']);而编辑某篇文章时,在PostController@update里调用$this->authorize('update', $post),由PostPolicy@update决定该用户能否改这篇特定文章。


















