认证与授权的区别
认证(Authentication) 用来确认用户「是谁」。登录处理就是典型例子。 授权(Authorization) 用来判断该用户「能做什么」。例如只能编辑自己发的帖子、只有管理员能修改设置等。 在通过认证实现登录功能后,下一步就是授权。Laravel 的授权功能提供 Gate 与 Policy 两种方式。选择哪种取决于用途。
Gate
Gate 是基于闭包的简单授权检查,适合与特定模型无关的权限判断。Gate 的授权流程
定义 Gate
Gate 定义在App\Providers\AppServiceProvider 的 boot 方法中,使用 Gate::define()。
使用 Gate 检查权限
在控制器中使用 Gate 检查权限可用Gate::allows() 或 Gate::denies()。
使用 Gate::authorize() 抛出异常
无权限时自动返回 403 响应可以使用Gate::authorize(),省去手写 abort(403)。
管理员绕过(before 方法)
若想给管理员用户所有权限,可以使用Gate::before()。
before 闭包返回非 null 值,将其作为最终结果。返回 null 或无返回值时会继续执行正常的 Gate 判定。
Blade 中的 @can / @cannot
在模板中使用 Gate,可用@can 与 @cannot 指令:
Policy
Policy 将某模型相关的授权逻辑归入一个类。对Post 模型的创建、查看、编辑、删除等权限,用 Policy 比 Gate 更合适。
Policy 的授权流程
生成 Policy
使用make:policy Artisan 命令生成 Policy 类。
--model:
app/Policies/PostPolicy.php。
模型与 Policy 的自动识别
Laravel 默认根据命名约定自动识别 Policy:- 模型:
app/Models/Post.php - Policy:
app/Policies/PostPolicy.php
若不遵循命名约定或希望手动注册,可在 在 Laravel 13 中,也可以通过
AppServiceProvider 的 boot 中使用 Gate::policy():#[UsePolicy] 属性在模型上进行声明式注册。实现 Policy 方法
通过--model 生成的 Policy 已经带有标准 CRUD 方法。
管理员绕过(before 方法)
Policy 中也可通过before 给管理员所有权限:
before 回调的执行顺序
在控制器中使用 Policy
authorize() 方法
Laravel 控制器提供了authorize() 帮助方法(若未使用基础控制器,可使用 Gate::authorize())。
- User::can() / cannot()
使用 authorizeResource() 一次注册 RESTful Policy
在构造器中调用authorizeResource(),可以将控制器各个 action 自动映射到对应 policy 方法。
在中间件中授权
在路由级做授权检查,使用can 中间件。
can 方法写得更简洁:
在 Blade 中使用 Policy
注册好 Policy 之后,Blade 的@can / @cannot 指令也会自动使用 Policy。
实用示例:博客文章权限管理
在博客应用中实现「作者才能编辑或删除自己的文章」:1
生成 Policy
2
实现 Policy 方法
3
在控制器中添加 authorizeResource()
4
在 Blade 模板中添加权限判断
小结
Gate 与 Policy 的选择
Gate 与 Policy 的选择
- Gate:与特定模型无关的简单权限判断。例如管理后台访问、全局设置修改权限等。
- Policy:针对模型的 CRUD 权限。为
Post、Order、Comment等资源分别建立 policy 类。
常用 API 汇总
常用 API 汇总
常用 Artisan 命令
常用 Artisan 命令