Skip to content
Icon

ПРЕДУПРЕЖДЕНИЕ Вы просматриваете документацию к старой версии Laravel. Рассмотрите возможность обновления Вашего проекта до Laravel 9.x.

Авторизация

Введение

Помимо предоставления встроенных служб аутентификации, Laravel также предоставляет простой способ авторизации действий пользователя в отношении данного ресурса. Например, даже если пользователь аутентифицирован, он может не иметь права обновлять или удалять определенные модели Eloquent или записи базы данных, управляемые вашим приложением. Функции авторизации Laravel обеспечивают простой и организованный способ управления этими типами проверок авторизации.

Laravel предоставляет два основных способа авторизации действий: гейты и политики. Думайте о шлюзах и политиках как о маршрутах и ​​контроллерах. Шлюзы обеспечивают простой подход к авторизации на основе замыкания, в то время как политики, такие как контроллеры, группируют логику вокруг конкретной модели или ресурса. В этой документации мы сначала рассмотрим шлюзы, а затем изучим политики.

Вам не нужно выбирать между исключительно использованием шлюзов или исключительно использованием политик при создании приложения. Большинство приложений, скорее всего, будут содержать некоторую смесь шлюзов и политик, и это совершенно нормально! Шлюзы наиболее применимы к действиям, не связанным с какой-либо моделью или ресурсом, например к просмотру панели администратора. Напротив, политики следует использовать, когда вы хотите авторизовать действие для конкретной модели или ресурса.

Гейты

Написание гейтов

{note} Gates — отличный способ изучить основы функций авторизации Laravel; однако при создании надежных приложений Laravel вам следует рассмотреть возможность использования политик для организации ваших правил авторизации.

Шлюзы — это просто замыкания, которые определяют, авторизован ли пользователь для выполнения данного действия. Как правило, шлюзы определяются в методе boot класса App\Providers\AuthServiceProvider с использованием фасада Gate. Gates всегда получает пользовательский экземпляр в качестве своего первого аргумента и может дополнительно получать дополнительные аргументы, такие как соответствующая модель Eloquent.

В этом примере мы определим шлюз, чтобы определить, может ли пользователь обновить данную модель App\Models\Post. Гейт выполнит это, сравнив id пользователя с user_id пользователя, создавшего сообщение:

use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Gate;
 
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
 
Gate::define('update-post', function (User $user, Post $post) {
return $user->id === $post->user_id;
});
}

Как и контроллеры, гейты также могут быть определены с использованием массива обратного вызова класса:

use App\Policies\PostPolicy;
use Illuminate\Support\Facades\Gate;
 
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
 
Gate::define('update-post', [PostPolicy::class, 'update']);
}

Авторизация действий

Чтобы авторизовать действие с помощью гейта, вы должны использовать методы allows или denies, предоставляемые фасадом Gate. Обратите внимание, что вам не требуется передавать этим методам пользователя, прошедшего проверку подлинности в данный момент. Laravel автоматически позаботится о переходе пользователя к замыканию гейта. Обычно методы авторизации шлюза вызываются в контроллерах вашего приложения перед выполнением действия, требующего авторизации:

<?php
 
namespace App\Http\Controllers;
 
use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
 
class PostController extends Controller
{
/**
* Update the given post.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Post $post
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Post $post)
{
if (! Gate::allows('update-post', $post)) {
abort(403);
}
 
// Update the post...
}
}

Если вы хотите определить, авторизован ли пользователь, отличный от текущего аутентифицированного пользователя, для выполнения действия, вы можете использовать метод forUser на фасаде Gate:

if (Gate::forUser($user)->allows('update-post', $post)) {
// The user can update the post...
}
 
if (Gate::forUser($user)->denies('update-post', $post)) {
// The user can't update the post...
}

Вы можете авторизовать несколько действий одновременно, используя методы any или none:

if (Gate::any(['update-post', 'delete-post'], $post)) {
// The user can update or delete the post...
}
 
if (Gate::none(['update-post', 'delete-post'], $post)) {
// The user can't update or delete the post...
}

Авторизация или создание исключений

Если вы хотите попытаться авторизовать действие и автоматически создать Illuminate\Auth\Access\AuthorizationException, если пользователю не разрешено выполнять данное действие, вы можете использовать метод authorize фасада Gate. Экземпляры AuthorizationException автоматически преобразуются в HTTP-ответ 403 обработчиком исключений Laravel:

Gate::authorize('update-post', $post);
 
// The action is authorized...

Предоставление дополнительного контекста

Методы гейта для авторизации способностей (allows, denies, check, any, none, authorize, can, cannot) и авторизации директивы блейда (@can, @cannot, @canany) могут получать массив в качестве второго аргумента. Эти элементы массива передаются в качестве параметров для замыкания гейта и могут использоваться для дополнительного контекста при принятии решений об авторизации:

use App\Models\Category;
use App\Models\User;
use Illuminate\Support\Facades\Gate;
 
Gate::define('create-post', function (User $user, Category $category, $pinned) {
if (! $user->canPublishToGroup($category->group)) {
return false;
} elseif ($pinned && ! $user->canPinPosts()) {
return false;
}
 
return true;
});
 
if (Gate::check('create-post', [$category, $pinned])) {
// The user can create the post...
}

Ответы гейта

До сих пор мы рассматривали только гейты, которые возвращают простые логические значения. Однако иногда вы можете захотеть вернуть более подробный ответ, включая сообщение об ошибке. Для этого вы можете вернуть Illuminate\Auth\Access\Response от вашего гейта:

use App\Models\User;
use Illuminate\Auth\Access\Response;
use Illuminate\Support\Facades\Gate;
 
Gate::define('edit-settings', function (User $user) {
return $user->isAdmin
? Response::allow()
: Response::deny('You must be an administrator.');
});

Даже если вы вернете ответ авторизации от своего шлюза, метод Gate::allows все равно вернет простое логическое значение; однако вы можете использовать метод Gate::inspect, чтобы получить полный ответ авторизации, возвращаемый гейтом:

$response = Gate::inspect('edit-settings');
 
if ($response->allowed()) {
// The action is authorized...
} else {
echo $response->message();
}

При использовании метода Gate::authorize, который генерирует исключение AuthorizationException, если действие не авторизовано, сообщение об ошибке, предоставленное ответом авторизации, будет распространено на ответ HTTP:

Gate::authorize('edit-settings');
 
// The action is authorized...

Перехватывание проверок гейтов

Иногда вы можете захотеть предоставить все возможности конкретному пользователю. Вы можете использовать метод before, чтобы определить замыкание, которое запускается перед всеми другими проверками авторизации:

use Illuminate\Support\Facades\Gate;
 
Gate::before(function ($user, $ability) {
if ($user->isAdministrator()) {
return true;
}
});

Если замыкание before возвращает ненулевой результат, этот результат будет считаться результатом проверки авторизации.

Вы можете использовать метод after для определения замыкания, которое будет выполняться после всех других проверок авторизации:

Gate::after(function ($user, $ability, $result, $arguments) {
if ($user->isAdministrator()) {
return true;
}
});

Подобно методу before если замыкание after возвращает ненулевой результат, этот результат будет считаться результатом проверки авторизации.

Встроенная авторизация

Иногда вы можете захотеть определить, авторизован ли текущий аутентифицированный пользователь для выполнения данного действия без записи специального шлюза, соответствующего действию. Laravel позволяет вам выполнять эти типы «встроенных» проверок авторизации с помощью методов Gate::allowIf и Gate::denyIf:

use Illuminate\Support\Facades\Auth;
 
Gate::allowIf(fn ($user) => $user->isAdministrator());
 
Gate::denyIf(fn ($user) => $user->banned());

Если действие не авторизовано или в настоящее время ни один пользователь не аутентифицирован, Laravel автоматически выдаст исключение Illuminate\Auth\Access\AuthorizationException. Экземпляры AuthorizationException автоматически преобразуются в HTTP-ответ 403 обработчиком исключений Laravel:

Создание политик

Создание политик

Политики — это классы, организующие логику авторизации для конкретной модели или ресурса. Например, если ваше приложение представляет собой блог, у вас может быть модель App\Models\Post и соответствующая модель App\Policies\PostPolicy для авторизации действий пользователя, таких как создание или обновление сообщений.

Вы можете сгенерировать политику с помощью Artisan-команды make:policy. Сгенерированная политика будет помещена в каталог app/Policies. Если этот каталог не существует в вашем приложении, Laravel создаст его для вас:

php artisan make:policy PostPolicy

Команда make:policy создаст пустой класс политики. Если вы хотите сгенерировать класс с примерами методов политики, связанных с просмотром, созданием, обновлением и удалением ресурса, вы можете указать параметр --model при выполнении команды:

php artisan make:policy PostPolicy --model=Post

Регистрация политик

После создания класса политики его необходимо зарегистрировать. Регистрация политик — это то, как мы можем сообщить Laravel, какую политику использовать при авторизации действий с данным типом модели.

App\Providers\AuthServiceProvider, включенный в новые приложения Laravel, содержит свойство policies, которое сопоставляет ваши модели Eloquent с соответствующими политиками. Регистрация политики сообщит Laravel, какую политику использовать при авторизации действий с данной моделью Eloquent:

<?php
 
namespace App\Providers;
 
use App\Models\Post;
use App\Policies\PostPolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
 
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
Post::class => PostPolicy::class,
];
 
/**
* Register any application authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
 
//
}
}

Автоматическое обнаружение политик

Вместо того, чтобы вручную регистрировать политики моделей, Laravel может автоматически обнаруживать политики, если модель и политика соответствуют стандартным соглашениям об именах Laravel. В частности, политики должны находиться в каталоге Policies в каталоге, содержащем ваши модели, или над ним. Так, например, модели могут быть помещены в каталог app/Models, а политики — в каталог app/Policies. В этой ситуации Laravel проверит наличие политик в app/Models/Policies, а затем в app/Policies. Кроме того, имя политики должно совпадать с названием модели и иметь суффикс Policy. Таким образом, модель User будет соответствовать классу политики UserPolicy.

Если вы хотите определить свою собственную логику обнаружения политики, вы можете зарегистрировать обратный вызов для обнаружения пользовательской политики, используя метод Gate::guessPolicyNamesUsing. Как правило, этот метод следует вызывать из метода boot вашего приложения AuthServiceProvider:

use Illuminate\Support\Facades\Gate;
 
Gate::guessPolicyNamesUsing(function ($modelClass) {
// Return the name of the policy class for the given model...
});

{note} Любые политики, которые явно отображаются в вашем AuthServiceProvider, будут иметь приоритет над любыми потенциально автоматически обнаруженными политиками.

Написание политик

Методы политики

После регистрации класса политики вы можете добавить методы для каждого действия, которое он разрешает. Например, давайте определим метод update для нашей PostPolicy, который определяет, может ли данное App\Models\User обновить данный экземпляр App\Models\Post.

Метод update получает экземпляр User и Post в качестве своих аргументов и должен возвращать true или false, указывая, имеет ли пользователь право обновлять данный Post. Итак, в этом примере мы проверим, что id пользователя соответствует user_id в сообщении:

<?php
 
namespace App\Policies;
 
use App\Models\Post;
use App\Models\User;
 
class PostPolicy
{
/**
* Determine if the given post can be updated by the user.
*
* @param \App\Models\User $user
* @param \App\Models\Post $post
* @return bool
*/
public function update(User $user, Post $post)
{
return $user->id === $post->user_id;
}
}

Вы можете продолжать определять дополнительные методы политики по мере необходимости для различных действий, которые она разрешает. Например, вы можете определить методы view или delete для авторизации различных действий, связанных с Post, но помните, что вы можете дать своим методам политики любое имя, которое вам нравится.

Если вы использовали параметр --model при создании политики через консоль Artisan, она уже будет содержать методы для действия viewAny, view, create, update, delete, restore и forceDelete.

{tip} Все политики разрешаются через сервисный контейнер, что позволяет вам указать любые необходимые зависимости в конструкторе политики, чтобы они были автоматически внедрены.

Ответы политики

До сих пор мы рассматривали только методы политики, которые возвращают простые логические значения. Однако иногда вы можете захотеть вернуть более подробный ответ, включая сообщение об ошибке. Для этого вы можете вернуть экземпляр Illuminate\Auth\Access\Response из метода вашей политики:

use App\Models\Post;
use App\Models\User;
use Illuminate\Auth\Access\Response;
 
/**
* Determine if the given post can be updated by the user.
*
* @param \App\Models\User $user
* @param \App\Models\Post $post
* @return \Illuminate\Auth\Access\Response
*/
public function update(User $user, Post $post)
{
return $user->id === $post->user_id
? Response::allow()
: Response::deny('You do not own this post.');
}

При возврате ответа авторизации из вашей политики метод Gate::allows по-прежнему будет возвращать простое логическое значение; однако вы можете использовать метод Gate::inspect, чтобы получить полный ответ авторизации, возвращаемый гейтом:

use Illuminate\Support\Facades\Gate;
 
$response = Gate::inspect('update', $post);
 
if ($response->allowed()) {
// The action is authorized...
} else {
echo $response->message();
}

При использовании метода Gate::authorize, который генерирует исключение AuthorizationException, если действие не авторизовано, сообщение об ошибке, предоставленное ответом авторизации, будет распространено на ответ HTTP:

Gate::authorize('update', $post);
 
// The action is authorized...

Методы без моделей

Некоторые методы политики получают только экземпляр текущего аутентифицированного пользователя. Эта ситуация наиболее распространена при авторизации действий create. Например, если вы создаете блог, вы можете определить, имеет ли пользователь право создавать какие-либо сообщения. В этих ситуациях ваш метод политики должен ожидать только получения экземпляра пользователя:

/**
* Determine if the given user can create posts.
*
* @param \App\Models\User $user
* @return bool
*/
public function create(User $user)
{
return $user->role == 'writer';
}

Гостевые пользователи

По умолчанию все шлюзы и политики автоматически возвращают false, если входящий HTTP-запрос не был инициирован аутентифицированным пользователем. Однако вы можете разрешить этим проверкам авторизации проходить через ваши шлюзы и политики, объявив «необязательную» подсказку типа или предоставив null значение по умолчанию для определения пользовательского аргумента:

<?php
 
namespace App\Policies;
 
use App\Models\Post;
use App\Models\User;
 
class PostPolicy
{
/**
* Determine if the given post can be updated by the user.
*
* @param \App\Models\User $user
* @param \App\Models\Post $post
* @return bool
*/
public function update(?User $user, Post $post)
{
return optional($user)->id === $post->user_id;
}
}

Фильтры политик

Для некоторых пользователей вы можете разрешить все действия в рамках данной политики. Для этого определите в политике метод before. Метод before будет выполняться перед любыми другими методами политики, что дает вам возможность авторизовать действие до фактического вызова предполагаемого метода политики. Эта функция чаще всего используется для авторизации администраторов приложений для выполнения любых действий:

use App\Models\User;
 
/**
* Perform pre-authorization checks.
*
* @param \App\Models\User $user
* @param string $ability
* @return void|bool
*/
public function before(User $user, $ability)
{
if ($user->isAdministrator()) {
return true;
}
}

Если вы хотите запретить все проверки авторизации для определенного типа пользователей, вы можете вернуть false из метода before. Если возвращается null, проверка авторизации не выполняется методом политики.

{note} Метод before класса политики не будет вызываться, если класс не содержит метод с именем, совпадающим с именем проверяемой способности.

Авторизация действий с использованием политик

Через модель пользователя

Модель App\Models\User, включенная в ваше приложение Laravel, включает два полезных метода авторизации действий: can и cannot. Методы can и cannot получают имя действия, которое вы хотите разрешить, и соответствующую модель. Например, давайте определим, авторизован ли пользователь для обновления данной модели App\Models\Post. Как правило, это делается внутри метода контроллера:

<?php
 
namespace App\Http\Controllers;
 
use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\Request;
 
class PostController extends Controller
{
/**
* Update the given post.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Post $post
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Post $post)
{
if ($request->user()->cannot('update', $post)) {
abort(403);
}
 
// Update the post...
}
}

Если политика зарегистрирована для данной модели, метод can автоматически вызовет соответствующую политику и вернет логический результат. Если для модели не зарегистрирована политика, метод can попытается вызвать шлюз на основе замыкания, соответствующий заданному имени действия.

Действия, не требующие моделей

Помните, что некоторые действия могут соответствовать методам политики, таким как create, которые не требуют экземпляра модели. В таких ситуациях вы можете передать имя класса методу can. Имя класса будет использоваться для определения того, какую политику использовать при авторизации действия:

<?php
 
namespace App\Http\Controllers;
 
use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\Request;
 
class PostController extends Controller
{
/**
* Create a post.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
if ($request->user()->cannot('create', Post::class)) {
abort(403);
}
 
// Create the post...
}
}

Через помощники контроллера

В дополнение к полезным методам, предоставляемым модели App\Models\User, Laravel предоставляет полезный метод authorize для любого из ваших контроллеров, который расширяет базовый класс App\Http\Controllers\Controller.

Как и метод can, этот метод принимает имя действия, которое вы хотите авторизовать, и соответствующую модель. Если действие не авторизовано, метод авторизации вызовет исключение authorize method will throw an Illuminate\Auth\Access\AuthorizationException, которое обработчик исключений Laravel автоматически преобразует в HTTP-ответ с кодом состояния 403:

<?php
 
namespace App\Http\Controllers;
 
use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\Request;
 
class PostController extends Controller
{
/**
* Update the given blog post.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Post $post
* @return \Illuminate\Http\Response
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(Request $request, Post $post)
{
$this->authorize('update', $post);
 
// The current user can update the blog post...
}
}

Действия, не требующие моделей

Как обсуждалось ранее, некоторые методы политики, такие как create, не требуют экземпляра модели. В этих ситуациях вы должны передать имя класса методу авторизации authorize. Имя класса будет использоваться для определения того, какую политику использовать при авторизации действия:

use App\Models\Post;
use Illuminate\Http\Request;
 
/**
* Create a new blog post.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function create(Request $request)
{
$this->authorize('create', Post::class);
 
// The current user can create blog posts...
}

Авторизация контроллеров ресурсов

Если вы используете контроллеры ресурсов, вы можете использовать метод authorizeResource в конструкторе вашего контроллера. Этот метод прикрепит соответствующие определения мидлвара can к методам контроллера ресурсов.

Метод authorizeResource принимает имя класса модели в качестве первого аргумента и имя параметра маршрута/запроса, который будет содержать идентификатор модели, в качестве второго аргумента. Вы должны убедиться, что ваш контроллер ресурсов создан с использованием флага --model, чтобы он имел необходимые сигнатуры методов и подсказки типов:

<?php
 
namespace App\Http\Controllers;
 
use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\Request;
 
class PostController extends Controller
{
/**
* Create the controller instance.
*
* @return void
*/
public function __construct()
{
$this->authorizeResource(Post::class, 'post');
}
}

Следующие методы контроллера будут сопоставлены с соответствующим им методом политики. Когда запросы перенаправляются на данный метод контроллера, соответствующий метод политики будет автоматически вызываться перед выполнением метода контроллера:

Controller Method Policy Method
index viewAny
show view
create create
store create
edit update
update update
destroy delete

{tip} Вы можете использовать команду make:policy с параметром --model, чтобы быстро сгенерировать класс политики для данной модели: php artisan make:policy PostPolicy --model=Post.

Через мидлвар

Laravel включает мидлвар, которое может авторизовать действия еще до того, как входящий запрос достигнет ваших маршрутов или контроллеров. По умолчанию мидлвар Illuminate\Auth\Middleware\Authorize назначается ключ can в вашем классе App\Http\Kernel. Давайте рассмотрим пример использования мидлвара can для авторизации того, что пользователь может обновлять сообщение:

use App\Models\Post;
 
Route::put('/post/{post}', function (Post $post) {
// The current user may update the post...
})->middleware('can:update,post');

В этом примере мы передаем мидлвару can два аргумента. Первое — это имя действия, которое мы хотим авторизовать, а второе — параметр маршрута, который мы хотим передать методу политики. В этом случае, поскольку мы используем неявную привязку модели, методу политики будет передана модель App\Models\Post. Если пользователь не авторизован для выполнения данного действия, мидлвар вернет HTTP-ответ с кодом состояния 403.

For convenience, you may also attach the can middleware to your route using the can method:

use App\Models\Post;
 
Route::put('/post/{post}', function (Post $post) {
// The current user may update the post...
})->can('update', 'post');

Действия, не требующие моделей

Опять же, некоторые методы политики, такие как create, не требуют экземпляра модели. В этих ситуациях вы можете передать промежуточному программному обеспечению имя класса. Имя класса будет использоваться для определения того, какую политику использовать при авторизации действия:

Route::post('/post', function () {
// The current user may create posts...
})->middleware('can:create,App\Models\Post');

Specifying the entire class name within a string middleware definition can become cumbersome. For that reason, you may choose to attach the can middleware to your route using the can method:

use App\Models\Post;
 
Route::post('/post', function () {
// The current user may create posts...
})->can('create', Post::class);

Через шаблоны Blade

При написании шаблонов Blade вы можете захотеть отображать часть страницы только в том случае, если пользователь авторизован для выполнения данного действия. Например, вы можете захотеть показать форму обновления для сообщения в блоге, только если пользователь действительно может обновить сообщение. В этой ситуации вы можете использовать директивы @can и @cannot:

@can('update', $post)
<!-- The current user can update the post... -->
@elsecan('create', App\Models\Post::class)
<!-- The current user can create new posts... -->
@else
<!-- ... -->
@endcan
 
@cannot('update', $post)
<!-- The current user cannot update the post... -->
@elsecannot('create', App\Models\Post::class)
<!-- The current user cannot create new posts... -->
@endcannot

Эти директивы являются удобными сокращениями для написания операторов @if и @unless. Приведенные выше операторы @can и @cannot эквивалентны следующим операторам:

@if (Auth::user()->can('update', $post))
<!-- The current user can update the post... -->
@endif
 
@unless (Auth::user()->can('update', $post))
<!-- The current user cannot update the post... -->
@endunless

Вы также можете определить, авторизован ли пользователь для выполнения какого-либо действия из заданного набора действий. Для этого используйте директиву @canany:

@canany(['update', 'view', 'delete'], $post)
<!-- The current user can update, view, or delete the post... -->
@elsecanany(['create'], \App\Models\Post::class)
<!-- The current user can create a post... -->
@endcanany

Действия, не требующие моделей

Как и в большинстве других методов авторизации, вы можете передать имя класса в директивы @can и @cannot, если для действия не требуется экземпляр модели:

@can('create', App\Models\Post::class)
<!-- The current user can create posts... -->
@endcan
 
@cannot('create', App\Models\Post::class)
<!-- The current user can't create posts... -->
@endcannot

Предоставление дополнительного контекста

При авторизации действий с использованием политик вы можете передать массив в качестве второго аргумента различным функциям авторизации и помощникам. Первый элемент массива будет использоваться для определения того, какую политику следует вызывать, а остальные элементы массива передаются в качестве параметров методу политики и могут использоваться для дополнительного контекста при принятии решений об авторизации. Например, рассмотрим следующее определение метода PostPolicy, которое содержит дополнительный параметр $category:

/**
* Determine if the given post can be updated by the user.
*
* @param \App\Models\User $user
* @param \App\Models\Post $post
* @param int $category
* @return bool
*/
public function update(User $user, Post $post, int $category)
{
return $user->id === $post->user_id &&
$user->canUpdateCategory($category);
}

При попытке определить, может ли аутентифицированный пользователь обновить данный пост, мы можем вызвать этот метод политики следующим образом:

/**
* Update the given blog post.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Post $post
* @return \Illuminate\Http\Response
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(Request $request, Post $post)
{
$this->authorize('update', [$post, $request->category]);
 
// The current user can update the blog post...
}