soyhuce / laravel-fluent-policy
在 Laravel 中编写流畅的策略
1.6.0
2024-03-08 15:30 UTC
Requires
- php: ^8.2
- illuminate/auth: ^10.0 || ^11.0
- illuminate/contracts: ^10.0 || ^11.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.7
- larastan/larastan: ^2.0.1
- nunomaduro/collision: ^7.10 || ^8.1
- orchestra/testbench: ^8.0 || ^9.0
- pestphp/pest: ^2.24
- pestphp/pest-plugin-laravel: ^2.2
- phpstan/extension-installer: ^1.1
- phpstan/phpstan-deprecation-rules: ^1.0
- phpstan/phpstan-phpunit: ^1.0
This package is auto-updated.
Last update: 2024-08-30 00:13:08 UTC
README
在 Laravel 中流畅地编写您的策略。
<?php class PostPolicy extends FluentPolicy { public function delete(User $user, Post $post): Response { return $this->denyWhen($post->user_id !== $user->id) ->denyWhen($post->published_at !== null) ->allow(); } }
安装
您可以通过 composer 安装此包
composer require soyhuce/laravel-fluent-policy
使用方法
此包的目的是使您能够更容易地以干净的语法编写策略。
例如,以下策略
<?php use Illuminate\Auth\Access\HandlesAuthorization; class PostPolicy { use HandlesAuthorization; public function delete(User $user, Post $post): bool { if ($post->user_id !== $user->id) { return false; } if ($post->published_at !== null) { return false; } return true; } }
可以重写为
<?php use Illuminate\Auth\Access\Response; use Soyhuce\FluentPolicy\FluentPolicy; class PostPolicy extends FluentPolicy { public function delete(User $user, Post $post): Response { return $this->denyWhen($post->user_id !== $user->id) ->denyWhen($post->published_at !== null) ->allow(); } }
如果需要,您可以自定义响应
return $this->denyWhen($post->published_at !== null, 'You cannot delete a published post') ->allow();
您也可以这样调用另一个策略或门控
return $this->authorize($user, 'update', $post) ->allowWhen($post->published_at === null) ->deny();
自定义 HTTP 状态
您可以通过返回自定义 HTTP 状态码来拒绝策略
return $this->denyWithStatusWhen($post->user_id !== $user->id, 404) ->allow(); // or $this->>allowWhen(...)->denyWithStatus(404);
在 404
状态码的情况下,您可以使用快捷方式
return $this->denyAsNotFoundWhen($post->user_id !== $user->id) ->allow(); // or $this->>allowWhen(...)->denyAsNotFound();
懒加载评估
不同的分支 allowWhen
和 denyWhen
是懒加载评估的,这意味着以下代码是完全正确的
<?php use Illuminate\Auth\Access\Response; use Soyhuce\FluentPolicy\FluentPolicy; class PostPolicy extends FluentPolicy { public function delete(User $user, Post $post): Response { // Here, $post->published_at is Carbon or null return $this->denyWhen($post->user_id !== $user->id) ->allowWhen($post->published_at === null) // 1 ->allowWhen($post->published_at->isFuture()) // 2 ->deny(); } }
2
只有在之前的分支都为假时才会调用。我们通过 1
确保这里 $post->published_at
不是 null。
PHPStan
当在
public function delete(User $user, Post $post): Response { return $this->denyWhen($post->user_id !== $user->id) ->allowWhen($post->published_at === null) // 1 ->allowWhen($post->published_at->isFuture()) // 2 ->deny(); }
上运行 PHPStan 时
在 2
上抛出错误(Cannot call method isFuture on Carbon|null
)。
includes: - vendor/bin/soyhuce/laravel-fluent-policies/extension.neon
遗憾的是,由于 PHPStan 的限制,您仍然需要稍微重写您的策略
public function delete(User $user, Post $post): Response { $this->denyWhen($post->user_id !== $user->id) ->allowWhen($post->published_at === null); // From here, PHPStan understands that $post->published_at is not null return $this->allowWhen($post->published_at->isFuture()) ->deny(); }
测试
composer test
变更日志
请参阅 CHANGELOG 了解最近更改的更多信息。
贡献
请参阅 CONTRIBUTING 了解详细信息。
安全漏洞
请查看我们如何报告安全漏洞的 安全策略。
鸣谢
许可
MIT 许可证(MIT)。请参阅 许可文件 了解更多信息。