Policy:基于模型的授权
将 Policy 关联到 Eloquent 模型,并在控制器中使用它们。
Policy:基于模型的授权 是 CoddyKit 上的免费 PHP Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 PHP Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 PHP Academy 课程共包含 4 节课。
什么是策略?
策略是用于组织特定 Eloquent 模型授权逻辑的类。当同一模型有多个授权操作时,建议使用策略。
生成策略
使用 Artisan 生成策略。添加 --model 可预先填充标准方法。
$ php artisan make:policy PostPolicy --model=Post策略方法
每个方法对应一个操作。它接收已通过身份验证的用户和模型实例。
<?php
class PostPolicy
{
public function view(?User $user, Post $post): bool
{
return $post->is_published || $user?->id === $post->user_id;
}
public function update(User $user, Post $post): bool
{
return $user->id === $post->user_id;
}
public function delete(User $user, Post $post): bool
{
return $user->id === $post->user_id || $user->isAdmin();
}
}注册策略
在 Laravel 11 及更高版本中,只要遵循命名约定,策略就会被自动发现(Post 模型 → PostPolicy)。您也可以在 AuthServiceProvider 中手动注册。
在控制器中使用策略
调用 $this->authorize("action", $model),Laravel 会自动找到匹配的策略。
<?php
public function update(Request $request, Post $post): RedirectResponse
{
$this->authorize("update", $post);
$post->update($request->validated());
return redirect()->route("posts.show", $post);
}Blade 中的策略
@can 指令对策略的作用方式与对 Gate 的作用方式相同。
@can('update', $post)
<a href="/posts/{{ $post->id }}/edit">Edit</a>
@endcanbefore() 方法
策略中可选的 before() 方法会在其他方法之前运行。返回 true 可授予全面访问权限(例如授予管理员)。
<?php
public function before(User $user, string $ability): ?bool
{
if ($user->isAdmin()) return true;
return null; // continue to specific method
}创建操作(无模型实例)
create 策略方法只接收用户(不接收模型),因为此时还不存在模型实例。
<?php
public function create(User $user): bool
{
return $user->hasVerifiedEmail();
}手动检查策略
使用 Gate 外观或用户模型直接检查策略。
<?php
Gate::allows("update", $post); // true/false
$user->can("update", $post); // true/false
$user->cannot("delete", $post); // true/false策略响应
从策略方法返回 Response 对象,以自定义拒绝消息。
<?php
use Illuminate\Auth\Access\Response;
public function publish(User $user, Post $post): Response
{
return $user->isEditor()
? Response::allow()
: Response::deny("Only editors can publish posts.");
}测试策略
在 PHPUnit 中以特定用户身份执行操作来测试策略。
<?php
public function test_owner_can_delete_post(): void
{
$user = User::factory()->create();
$post = Post::factory()->create(["user_id" => $user->id]);
$this->assertTrue($user->can("delete", $post));
}总结
策略用于集中管理模型级授权。使用 make:policy --model 生成策略。在控制器中使用 $this->authorize(),在 Blade 中使用 @can。使用 before() 绕过管理员检查。
快速检查
哪个策略方法只接收用户而不接收模型实例?
用 AI 导师学习 PHP — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 49
- 课程
- 195
常见问题解答
「Policy:基于模型的授权」课时是免费的吗?
是的 — 「Policy:基于模型的授权」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 PHP Academy 课程的其余内容,请升级到 CoddyKit PRO。 PHP Academy 课程共包含 4 节课。
「Policy:基于模型的授权」这节课中我会学到什么?
将 Policy 关联到 Eloquent 模型,并在控制器中使用它们。 你通过在浏览器中直接运行的动手代码来练习 PHP Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 PHP Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 PHP Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「Policy:基于模型的授权」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 PHP Academy 课中编写并运行代码吗?
能。每节 PHP Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 使用 Laravel Breeze 进行身份验证
- 使用中间件保护路由
- Gate:简单的授权检查
- Policy:基于模型的授权