Класс Policy
Класс Policy предназначен для группировки правил авторизации,
связанных с определённой моделью. В одном классе-политике
определяются методы, которые проверяют, может ли текущий пользователь
выполнить то или иное действие. В первом параметре метода
передаётся экземпляр пользователя, во втором - модель, если действие
связано с конкретной записью.
Синтаксис
<?php
namespace AppPolicies;
use AppModelsUser;
use AppModelsPost;
class PostPolicy
{
public function view(User $user, Post $post): bool
{
// logic
}
}
?>
Пример
Давайте создадим политику для модели 'Post'
с помощью команды make:policy:
<?php
php artisan make:policy PostPolicy --model=Post
?>
Результат выполнения команды:
"INFO Policy [app/Policies/PostPolicy.php] created successfully."
Пример
Давайте реализуем методы политики для проверки прав на просмотр, создание, обновление и удаление поста:
<?php
namespace AppPolicies;
use AppModelsUser;
use AppModelsPost;
class PostPolicy
{
public function view(User $user, Post $post): bool
{
return $user->id === $post->user_id;
}
public function create(User $user): bool
{
return $user->is_admin === true;
}
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->is_admin === true;
}
}
?>
Пример
Давайте зарегистрируем политику в сервис-провайдере для автоматического определения:
<?php
namespace AppProviders;
use IlluminateFoundationSupportProvidersAuthServiceProvider as ServiceProvider;
use AppModelsPost;
use AppPoliciesPostPolicy;
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
Post::class => PostPolicy::class,
];
public function boot(): void
{
$this->registerPolicies();
}
}
?>
Пример
Давайте воспользуемся политикой в контроллере
с помощью метода authorize:
<?php
namespace AppHttpControllers;
use AppModelsPost;
use IlluminateHttpRequest;
class PostController extends Controller
{
public function show(Post $post)
{
$this->authorize('view', $post);
return view('posts.show', ['post' => $post]);
}
public function destroy(Post $post)
{
$this->authorize('delete', $post);
$post->delete();
return redirect()->route('posts.index');
}
}
?>
Пример
Давайте проверим работу политики напрямую
с помощью фасада Gate:
<?php
use AppModelsUser;
use AppModelsPost;
use IlluminateSupportFacadesGate;
$user = User::find(1);
$post = Post::find(5);
$res = Gate::forUser($user)->allows('update', $post);
echo $res ? 'true' : 'false';
?>
Результат выполнения кода:
"true"
Пример
Давайте используем метод can для проверки прав
в шаблоне Blade:
@can('update', $post)
<a href="/posts/{{ $post->id }}/edit">Edit</a>
@endcan
@can('delete', $post)
<form action="/posts/{{ $post->id }}" method="POST">
@csrf
@method('DELETE')
<button type="submit">Delete</button>
</form>
@endcan