跳转到主要内容

认证与授权的区别

认证(Authentication) 用来确认用户「是谁」。登录处理就是典型例子。 授权(Authorization) 用来判断该用户「能做什么」。例如只能编辑自己发的帖子、只有管理员能修改设置等。 在通过认证实现登录功能后,下一步就是授权。
Laravel 的授权功能提供 Gate 与 Policy 两种方式。选择哪种取决于用途。
选择依据

Gate

Gate 是基于闭包的简单授权检查,适合与特定模型无关的权限判断。

Gate 的授权流程

定义 Gate

Gate 定义在 App\Providers\AppServiceProviderboot 方法中,使用 Gate::define()
Gate 闭包的第一个参数总是当前已认证用户。第二个及以后的参数可以传入目标模型等额外信息。

使用 Gate 检查权限

在控制器中使用 Gate 检查权限可用 Gate::allows()Gate::denies()

使用 Gate::authorize() 抛出异常

无权限时自动返回 403 响应可以使用 Gate::authorize(),省去手写 abort(403)
当权限不足时,Gate::authorize() 会抛出 Illuminate\Auth\Access\AuthorizationException。Laravel 会自动将其转换为 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 类。
若想生成包含对应模型 CRUD 方法的完整骨架,使用 --model
会生成 app/Policies/PostPolicy.php

模型与 Policy 的自动识别

Laravel 默认根据命名约定自动识别 Policy:
  • 模型:app/Models/Post.php
  • Policy:app/Policies/PostPolicy.php
只要遵循命名约定,就无需手动注册。
若不遵循命名约定或希望手动注册,可在 AppServiceProviderboot 中使用 Gate::policy()
在 Laravel 13 中,也可以通过 #[UsePolicy] 属性在模型上进行声明式注册。

实现 Policy 方法

通过 --model 生成的 Policy 已经带有标准 CRUD 方法。

管理员绕过(before 方法)

Policy 中也可通过 before 给管理员所有权限:
before 只会在 policy 类中存在对应方法时才会被调用。例如 update 方法不存在,before 就不会被调用。

before 回调的执行顺序

在控制器中使用 Policy

authorize() 方法

Laravel 控制器提供了 authorize() 帮助方法(若未使用基础控制器,可使用 Gate::authorize())。

使用 authorizeResource() 一次注册 RESTful Policy

在构造器中调用 authorizeResource(),可以将控制器各个 action 自动映射到对应 policy 方法。
action 与 policy 方法的对应关系:
使用 authorizeResource() 可以省去在每个 action 单独调用 authorize()。与 RESTful 资源控制器配合尤其方便。

在中间件中授权

在路由级做授权检查,使用 can 中间件。
也可以用 can 方法写得更简洁:

在 Blade 中使用 Policy

注册好 Policy 之后,Blade 的 @can / @cannot 指令也会自动使用 Policy。

实用示例:博客文章权限管理

在博客应用中实现「作者才能编辑或删除自己的文章」:
1

生成 Policy

2

实现 Policy 方法

3

在控制器中添加 authorizeResource()

4

在 Blade 模板中添加权限判断

小结

  • Gate:与特定模型无关的简单权限判断。例如管理后台访问、全局设置修改权限等。
  • Policy:针对模型的 CRUD 权限。为 PostOrderComment 等资源分别建立 policy 类。
最后修改于 2026年7月18日