Laravel: Gate и Policy
Что такое Laravel Gate
Laravel Gate — это простой способ определения правил контроля доступа. Он позволяет определять правила, определяющие, имеет ли пользователь право выполнять определённое действие или нет. Шлюз можно использовать для ограничения доступа к различным частям приложения на основе роли пользователя, разрешений или других критериев, которые вы определяете.
Шлюзы определяются в классе AuthServiceProvider
, который находится в каталоге app/Providers
. В методе boot
класса AuthServiceProvider
вы можете определить свои шлюзы используя фасад Gate
предоставленный Laravel.
Пример определения Laravel шлюза проверяющий авторизован ли пользователь для обновления поста:
Gate::define('update-post', function ($user, $post) {
return $user->id === $post->user_id;
});
В приведённом выше коде мы определяем шлюз с именем update-post
. Первый аргумент — это имя шлюза, а второй аргумент замыкание, определяющее логику шлюза. Замыкание принимает два аргумента: $user
и $post
. Аргумент $user
— это аутентифицированный объект User
, а аргумент $post
— это объект Post
, который пользователь хочет обновить.
Замыкание возвращает true
, если пользователю разрешено обновлять пост, и false
в противном случае. В этом примере мы проверяем, соответствует ли идентификатор пользователя идентификатору пользователя поста (прим.: автор поста?). Если они совпадают, мы возвращаем true
, указывая, что пользователь авторизован для обновления поста.
Чтобы использовать Laravel Шлюз для маршрута, вы можете использовать middleware can
, предоставляемое Laravel. Middleware can
проверяет, авторизован ли аутентифицированный пользователь для выполнения определённого действия на основе определённого шлюза.
Пример использования шлюза Laravel для маршрута:
Route::get('/post/{post}', function (Post $post) {
// проверяем, может ли аутентифицированный пользователь обновить пост
if (Gate::allows('update-post', $post)) {
// возвращаем view для обновления поста
return view('update-post', ['post' => $post]);
} else {
// возвращаем ответ 403 Forbidden
abort(403);
}
})->middleware('can:update-post,post');
В приведённом выше коде мы определяем маршрут принимающий объект пост в качестве параметра. Прежде чем вернуть представление (view) для обновления поста, мы проверяем, может ли аутентифицированный пользователь обновить пост, используя метод Gate::allows()
. Если пользователь авторизован для обновления сообщения, мы возвращаем представление для обновления сообщения. Если нет, возвращаем ответ 403 Forbidden
.
Для большей эффективности мы можем использовать middleware can
для автоматической проверки, авторизован ли пользователь для выполнения действия определённого в шлюзе. В приведённом выше примере мы добавили middleware('can:update-post,post')
к определению маршрута. Это middleware автоматически проверяет, может ли аутентифицированный пользователь обновить пост с помощью шлюза update-post
. Если пользователь авторизован, middleware продолжит выполнять обработчик маршрута. Если нет, middleware вернёт ответ 403 Forbidden
.
Использование middleware can
— удобный способ защитить маршруты с помощью Laravel шлюзов. Это позволяет определять правила управления доступом в центральной локации и применять их к нескольким маршрутам в приложении.
Что такое Laravel Policy
Политики Laravel похожи на шлюзы, но более мощные и гибкие. Политики позволяют определить логику авторизации для конкретной модели или ресурса. Например, вы можете определить политику для модели Post
, которая определяет правила управления доступом для создания, обновления, удаления и просмотра постов.
Как и шлюзы, политики Laravel определяются в классе AuthServiceProvider
. Однако вместо определения замыкания вы определяете классы политики инкапсулирующие логику авторизации для конкретной модели или ресурса.
Пример определения Laravel политики для модели Post
:
class PostPolicy
{
public function update(User $user, Post $post)
{
return $user->id === $post->user_id;
}
}
В приведённом выше коде мы определяем класс политики с именем PostPolicy
. У класса есть публичный метод update
принимающий два аргумента: $user
и $post
. Аргумент $user
— это аутентифицированный объект User
, а аргумент $post
— это объект Post
, который пользователь хочет обновить.
Метод update
возвращает true
, если пользователь имеет право обновлять пост, и false
в противном случае. В этом примере мы проверяем, соответствует ли идентификатор пользователя идентификатору пользователя поста (прим. автор поста?). Если они совпадают, мы возвращаем true
, указывая, что пользователь авторизован для обновления поста.
Для использования класса PostPolicy
его необходимо зарегистрировать в классе AuthServiceProvider
:
protected $policies = [
Post::class => PostPolicy::class,
];
В приведённом выше коде мы регистрируем модель Post
с соответствующим классом политики PostPolicy
. Теперь Laravel знает, что необходимо использовать класс PostPolicy
для авторизации действий в модели Post
.
Для использования политики в контроллере, необходимо сначала авторизовать запрос пользователя с помощью политики. Laravel предоставляет метод authorize
, который вы можете вызвать для авторизации запроса пользователя перед выполнением метода контроллера.
Пример использования Laravel политики в контроллере:
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function update(Request $request, Post $post)
{
$this->authorize('update', $post);
// обновление поста
}
}
В приведённом выше примере кода мы определяем PostController
с методом update
принимающим два аргумента: $request
и $post
. Аргумент $request
— экземпляр класса Illuminate\Http\Request
, а аргумент $post
— пост, который пользователь хочет обновить.
Перед обновлением поста мы вызываем метод authorize
и передаём имя метода политики, который хотим использовать (update
), и объект $post
, для которого хотим авторизовать пользователя. Laravel будет автоматически искать соответствующий метод политики (update
) в классе политик (PostPolicy
), который мы зарегистрировали в AuthServiceProvider
.
Если пользователю разрешено обновление поста, метод контроллера продолжит выполнение. Если нет, Laravel автоматически выдаст исключение 403 Forbidden
.
Использование политик в контроллерах — мощный способ гарантировать, что только авторизованные пользователи могут получить доступ к определённым ресурсам или выполнить определённые действия. Это позволяет инкапсулировать логику авторизации в класс политики и поддерживать чистоту и читабельность кода контроллера.