Laravel Gates позволяет разрешить пользователям доступ к определенным областям вашего приложения. Вы можете легко определить “ворота” (gates) в своем приложении, а затем использовать их для разрешения или запрета доступа.
Давайте начнем с простого примера предоставления доступа без гейтов, а затем вы увидите, как мы можем использовать гейты в качестве альтернативы.
Простой пример
В нашей пользовательской таблице мы предположим, что у нас есть столбец с именем admin
, которое может быть 1
или 0
в зависимости от того, является ли пользователь администратором или нет. Мы могли бы легко защитить раздел нашего приложения, выполнив простую проверку:
Route::get('administration', function(){
if(auth()->check() && auth()->user()->admin){
echo 'Welcome to the admin section';
} else {
echo 'You shall not pass';
}
});
Если пользователь авторизован и поле admin заполнено, мы увидим следующие выходные данные.
В противном случае мы увидим следующее:
Это здорово! У нас есть простой способ разрешить или запретить доступ к определенному разделу в нашем приложении. Но вот в чем проблема. Что делать, если у нас есть эти проверки по всему нашему приложению и мы хотим изменить доступ пользователей? Мы должны были бы искать все места в нашем коде и изменять эту проверку везде. Не очень эффективно.
Вместо этого мы можем определить гейты и использовать их во всем нашем приложении.
Определение гейтов
Чтобы определить гейты, нам необходимо открыть наш App\Providers\AuthServiceProvider.php
файл и добавить в него следующее:
public function boot()
{
$this->registerPolicies();
Gate::define('access-admin', function ($user) {
return $user->admin;
});
}
Мы можем использовать этот гейт в любом месте, где мы хотим проверить пользователей-администраторов на протяжении всего нашего приложения. В следующем разделе вы увидите, как мы можем использовать эти новые гейты.
Использование гейтов
Чтобы использовать гейты мы можем вызвать метод Gate::allows()
или Gate::denies()
следующим образом:
Route::get('administration', function(){
if (Gate::allows('access-admin')) {
echo 'Welcome to the admin section';
} else {
echo 'You shall not pass';
}
});
Обратите внимание на
Gate::denies()
, этот метод выполняет обратную проверку наGate::allows()
Самое замечательное в этих гейтах то, что теперь мы можем изменить наше определение в любое время, и логика авторизации будет изменена на протяжении всего нашего приложения.
Еще одна причина использования гейтов – проверка разрешений, связанных с данными. Используя блог в качестве примера, мы можем разрешить пользователям редактировать созданные ими записи.
Мы можем передавать данные на наш шлюз, чтобы проверить, имеет ли пользователь разрешение на выполнение какого-либо действия.
Гейты с данными
Предположим , что наше приложение имеет таблицу Post со столбцом user_id
, который содержит идентификатор пользователя, создавшего его. Мы можем определить гейты, чтобы определить, может ли пользователь редактировать конкретный пост следующим образом:
Gate::define('edit-post', function ($user, $post) {
return $user->id === $post->user_id;
});
В наш гейт передаются два аргумента. Первый аргумент – это объект $user
, содержащий аутентифицированного пользователя, а второй аргумент-это наш объект $post
.
Гейт вернет false, если пользователь не авторизован
Этот гейт будет разрешать доступ, если аутентифицированный пользователь является первоначальным автором; в противном случае он будет запрещать доступ.
Вот краткий пример того, как мы могли бы использовать наши новые edit-post
гейты.
Route::get('edit/{id}', function($id){
$post = \App\Model\Post::find($id);
if( Gate::allows('edit-post', $post) ){
echo 'You can edit this post';
} else {
echo 'You shall not pass';
}
});
Выше мы используем замыкание маршрута в нашем примере, но, вероятно, хотим сопоставить этот маршрут контроллеру. Это также позволит нам использовать новый помощник авторизации.
Помощник авторизации
Помимо эффективности, еще одной причиной использования гейтов являются вспомогательные функции.
Предположим, что мы сопоставляем наш маршрут с контроллером:
Route::get('edit/{id}', 'PostController@edit');
Мы можем использовать authorize()
помощник, чтобы проверить, имеет ли аутентифицированный пользователь разрешение на редактирование записи:
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function edit($id){
$post = Post::find($id);
$this->authorize('edit-post', $post);
}
}
Если контроллер расширяется из App\Http\Controllers\Controller
базового класса, вы можете использовать authorize()
таким же образом, как вы использовали бы функцию Gate::allow()
.
Наконец, что делать, если мы хотим проверить авторизацию внутри представления? Мы можем использовать помощника @can
, чтобы сделать именно это.
Авторизация в ваших представлениях
Есть такой шаблон:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ $post->title }}</title>
</head>
<body>
<h1>{{ $post->title }}</h1>
<p>{!! $post->body !!}</p>
</body>
</html>
Мы можем проверить, что текущий пользователь имеет право редактировать этот пост, используя @can
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ $post->title }}</title>
</head>
<body>
<h1>{{ $post->title }}</h1>
<p>{!! $post->body !!}</p>
@can('edit-post', $post)
<a href="edit/{{ $post->id }}">Edit Post</a>
@endcan
</body>
</html>
Если аутентифицированный пользователь является первоначальным автором этого сообщения, он увидит кнопку Изменить сообщение.
Использование помощника @can
может облегчить чтение и управление нашим кодом. Вы также можете использовать @cannot
в качестве обратного.
Вывод
Это основы использования гейтов в вашем приложении Laravel. Ворота позволяют нам легко авторизовать доступ к областям нашего приложения для конкретных пользователей. Это также можно назвать списком управления доступом (ACL), списком разрешений, связанных с объектом.
Но мы не должны все усложнять… В своей простейшей форме гейты используются для разрешения или запрета доступа. Пользователь может либо войти в ворота, либо не войти в ворота.
Чтобы узнать больше о воротах Laravel, обязательно посетите документацию по авторизации..
Счастливого Разрешения 🔐