Ограничиваем доступ в админку Laravel

Ограничиваем доступ в админку Laravel

Для большинства сайтов возникает задача управления их содержимым, для этого создается особый раздел, назовем его «Панель администратора», в которой осуществляется контроль за сайтом. Само собой вход в эту панель нужно ограничить пользователями имеющими статус администратора. В этой статье мы реализуем этот функционал для админки сайта разрабатываемого с помощью фреймворка Laravel.

В этой статье я не буду рассматривать вариант когда пользователи имеющие доступ в Панель администратора разделяются на роли (администратор, редактор, сеошник), я рассмотрю только вариант с одной ролью — администратор имеющий доступ ко всем функциям админки.

В Ларавел есть управление пользователями «из коробки», но там не предусмотрено разделение на роли. Исправим это.

Добавление роли администратора

Если мы только создали проект и не делали еще ни одной миграции, можем просто в файл миграции пользователей добавим поле is_admin, этот файл идет в стандартной установке Laravel и располагается тут /database/migrations/XXXX_XX_XX_create_users_table.php

Добавим в функцию создания таблицы наше поле:

$table->boolean('is_admin')->default('0');

Должно получится что-то типа этого:

public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->boolean('is_admin')->default(0);
            $table->rememberToken();
            $table->timestamps();
        });
    }

Обратите внимание, значение по умолчанию я указал 0, чтобы каждый зарегистрировавшийся пользователь не становился админом.

Выполняем миграцию:

php artisan migrate

Добавляем поле в существующую таблицу

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

php artisan make:migration add_is_admin_to_users_table --table=users

В сгенерированном файле изменяем методы up() и down():

public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->boolean('is_admin')->default('0');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('is_admin');
        });
    }

Выполняем миграцию:

php artisan migrate

Модель User

Теперь добавим в модель User метод проверки пользователя на статус администратора isAdmin(). Модель User идет в стандартной установке Ларавел и располагается тут add/User.php

Добавляем наш метод в конце класса User:

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email','slug', 'password',
    ];

    .................

// Проверка пользователя на статус администратора
    public function isAdmin()
    {
        return $this->is_admin === 1;
    }
}

Middleware CheckIsAdmin

Остался завершающий этап. Предположим что панель администратора располагается у нас по адресу site.ru/admin, нам необходимо сделать чтобы в момент перехода по этому адресу осуществлялась проверка является ли пользователь администратором.

Это мы можем реализовать с помощью Middelware (Посредника), это такой удобный механизм в Laravel для фильтрации HTTP-запросов приложения. Посредник проверит есть ли у пользователя права админа и если есть пропустит его дальше, а если нет сделает редирект на главную страницу.

Создадим Middelware и назовем его CheckIsAdmin, выполним artisan команду:

php artisan make:middleware CheckIsAdmin

Наш Middelware создался и располагается в файле app/Http/Middleware/CheckIsAdmin.php. Откроем его и заменим функцию handle:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class CheckIsAdmin
{

    public function handle($request, Closure $next)
    {

        if(!Auth::user()->isAdmin()){
            return redirect()->route('index');
        }

        return $next($request);
    }
}

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

Мы использовали фассад Auth, но еще информацию о пользователе можно получить из запроса $request->user();

Middelware создан, теперь его нужно зарегистрировать. Чтобы это сделать, откроем файл app/Http/Kernel.php, в нем найдем массив protected $routeMiddleware и добавим в конце него наш класс:

 protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,

..........

        'isadmin' => \App\Http\Middleware\CheckIsAdmin::class,
    ];

Роутинг

Осталось указать какие пути сайта мы будем отслеживать. Зайдем в файл routes/web.php и добавим наш новый middelware в группу роутов, которая отвечает за панель администратора, например:

.......

// Админка
Route::group(['middleware' => ['auth', 'isadmin'], 'namespace' => 'Admin', 'prefix' => 'admin', 'as' => 'admin.'], function()
{
    Route::get('/home', 'HomeController@index')->name('home');

.......

    Route::resource('/categories', 'CategoryController');

    Route::get('/products/restore/{id}', 'ProductController@restore')->name('products.restore');
    Route::get('/products/trashed', 'ProductController@showTrashedProducts')->name('products.trashed');
    Route::resource('/products', 'ProductController');
});

.......

Здесь у нас уже был один middleware — auth, который отвечает за авторизацию, мы к нему добавили наш новый isadmin.

Теперь в админку (site.ru/admin) можно попасть только имея права администратора.

Шаблоны Blade

Кстати в шаблонах мы тоже можем проводить проверку на администратора. Например, мы хотим скрыть какую то ссылку от обычных пользователей и показывать ее только админу.

Для этого в шаблоне сделаем следующее:

@auth
     @if(Auth::user()->isAdmin())
         Это видит только админ
     @endif
@endauth

Хостинг для ваших проектов