laravel接口权限校验首选policy,它将“谁能在什么条件下操作哪个资源”封装进对应模型策略类,并通过$this->authorize()触发;需手动注册策略、定义规则方法(如update)、配合中间件实现粗细粒度双重防护。

Laravel 接口权限校验用 Policy 是最自然、最贴合模型语义的方式。核心不是写一堆 if 判断,而是把“谁能在什么条件下操作哪个资源”这个逻辑,封装进对应模型的策略类里,再通过统一入口触发检查。
生成并绑定策略类
策略必须和模型一一对应,并在框架中显式注册,否则 Laravel 不知道该调用哪个类。
- 运行命令生成策略:`php artisan make:policy PostPolicy --model=Post`,它会创建 `app/Policies/PostPolicy.php` 并尝试自动注册
- 打开 `app/Providers/AuthServiceProvider.php`,确认 `$policies` 数组包含:`'AppModelsPost' => 'AppPoliciesPostPolicy'`(注意命名空间要与实际模型路径一致)
- 如果模型放在 `app/Models/` 下,而自动注册没生效,需在 `AuthServiceProvider::boot()` 中手动配置策略发现逻辑,例如:
`Gate::guessPolicyNamesUsing(fn($class) => 'AppPolicies\' . class_basename($class) . 'Policy');`
在策略中定义具体规则
每个方法名通常对应一个动作(如 `view`、`update`、`delete`),接收当前用户和目标模型两个参数,返回布尔值。
- 示例:只允许文章作者或管理员编辑
- public function update(User $user, Post $post)
{
return $user->id === $post->user_id || $user->is_admin;
} - 未登录用户传入的 `$user` 为 null,Laravel 会自动让所有策略方法返回 false,无需额外判空
在 API 控制器中触发校验
控制器是 API 权限拦截的主要位置,推荐使用 `$this->authorize()`,它会自动调用对应策略并抛出标准 403 响应。
- 先查出模型实例,再授权:`$post = Post::findOrFail($id); $this->authorize('update', $post);`
- 也可以直接传模型类名和 ID(适用于未加载模型前快速判断):`$this->authorize('update', [Post::class, $id]);`
- 若需更灵活控制(比如返回自定义错误),可用门面:`Gate::allows('update', $post) || abort(403, '无权操作')`
配合中间件做前置粗粒度控制
Policy 处理的是“对某条数据能否执行某操作”,适合细粒度;中间件更适合“是否具备访问某类接口的资格”,比如限定仅管理员可访问用户管理接口。
- 创建中间件:`php artisan make:middleware CheckAdminRole`
- 在中间件中检查角色或权限:`if (!$request->user() || !$request->user()->hasRole('admin')) { abort(403); }`
- 将中间件应用到路由组:`Route::middleware('check.admin.role')->group(function () { ... });`
- 这样 Policy 和中间件就形成两层防护:中间件拦住不该进来的请求,Policy 拦住不该动那条数据的请求











