PHP Academy · 课时

Policy:基于模型的授权

将 Policy 关联到 Eloquent 模型,并在控制器中使用它们。

第 4 / 4 课13 个步骤

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>
@endcan

before() 方法

策略中可选的 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 反馈 — 无需本地设置。

此课程中的所有课时

  1. 使用 Laravel Breeze 进行身份验证
  2. 使用中间件保护路由
  3. Gate:简单的授权检查
  4. Policy:基于模型的授权
← 返回 PHP Academy