Создание кастомного guard аутентификации в Laravel

Создание кастомного guard аутентификации в Laravel

От автора: в этой статье мы рассмотрим систему аутентификации в фреймворке Laravel. Цель статьи – создать кастомный Guard аутентификации, расширив базовую систему аутентификации. Laravel предоставляет очень надежную систему аутентификации в ядре, что упрощает реализацию стандартной аутентификации. На деле, для установки системы аутентификации необходимо запустить пару выученных команд.

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

Элементы ядра: Guard и провайдеры

Система аутентификации Laravel состоит из двух элементов – Guard и провайдеры.

Guard

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

Guard определяет логику аутентификации, и необязательно, чтобы он постоянно получал валидные данные авторизации с back end. Можно сделать Guard, который просто проверяет наличие определенных данных в заголовках запроса и на их основе проводит аутентификацию.

Ниже в статье мы создадим Guard проверки определенных JSON параметров в заголовках запроса, который будет получать валидного пользователя с MongoDB back end.

Провайдеры

Если Guard определяет логику аутентификации, то провайдер аутентификации получает пользователя с хранилища back end. Если Guard требует, чтобы пользователь проверялся через back end хранилище, то реализация получения пользователя переходит в провайдер аутентификации.

Laravel идет с двумя стандартными провайдерами аутентификации — Database и Eloquent. Провайдер аутентификации Database работает с простым вытягиванием данных авторизации пользователя из хранилища back end, а Eloquent дает абстрактный слой.

В нашем примере мы реализуем провайдер аутентификации MongoDB, который будет получать данные авторизации пользователя через MongoDB back end.

Это было базовое представление Guard и провайдеров в системе аутентификации Laravel. Начиная со следующего раздела, мы будем разрабатывать кастомные Guard аутентификации и провайдер!

Быстрая настройка файлов

Давайте быстро пробежимся по файлам, которые нам необходимо создать в этой статье.

config/auth.php: файл настроек аутентификации, в который мы добавим точку входа в кастомный Guard.

config/mongo.php: файл для настроек MongoDB.

app/Services/Contracts/NosqlServiceInterface.php: интерфейс, который реализует наш кастомный класс Mongo database.

app/Database/MongoDatabase.php: главный класс базы данных, взаимодействующий с MongoDB.

app/Models/Auth/User.php: класс модели User, реализующий договор Authenticable.

app/Extensions/MongoUserProvider.php: реализация провайдера аутентификации.

app/Services/Auth/JsonGuard.php: реализация Guard драйвера аутентификации.

app/Providers/AuthServiceProvider.php: файл, с помощью которого мы будем добавлять привязки к сервис контейнерам.

app/Http/Controllers/MongoController.php: файл демо контроллера, с помощью которого мы будем тестировать наш кастомный Guard.

Не пугайтесь, что список файлов пока что вам ничего не говорит, мы постепенно все разберем.

Реализация

В этом разделе мы создадим необходимые файлы. Первым делом нам необходимо информировать Laravel о кастомном Guard. Скопируйте код ниже в файл config/auth.php.

Как видите, мы добавили кастомный Guard под ключом custom. Далее необходимо добавить соответствующий провайдер в раздел providers.

Провайдер добавлен под ключом mongo. Изменим стандартный Guard аутентификации с web на custom.

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

Создание MongoDB Driver

В этом разделе мы создадим необходимые файлы, которые будут общаться с объектом MongoDB. Сначала создадим файл настроек config/mongo.php, в котором будут храниться стандартные настройки подключения MongoDB.

Данные необходимо заменить на свои. Вместо класса, взаимодействующего с MongoDB мы создадим интерфейс.

Плюс интерфейса в том, что он дает абстрактность, которой разработчик должен придерживаться при его реализации. Также нашу реализацию MongoDB можно легко заменить на другую NoSQL реализацию без необходимости.

Создайте файл интерфейса app/Services/Contracts/NosqlServiceInterface.php и добавьте в него код ниже.

Простой интерфейс, определяющий CRUD методы, которые должен определить класс, реализующий этот интерфейс. Теперь создадим класс app/Database/MongoDatabase.php.

Предполагаю, что вы уже установили MongoDB и соответствующее расширение MongoDB PHP.

Метод __construct создает объект класса MongoClient с необходимыми параметрами. Другой важный метод, нужный нам – find. Он получает запись на основе переданных аргументов. Мы реализовали драйвер MongoDB и постарались сохранить его простоту.

Создание модели User

Придерживаясь стандартов системы аутентификации, нам необходимо реализовать модель User, которая должна реализовывать контракт Illuminate\Contracts\Auth\Authenticatable. Создайте файл app/Models/Auth/User.php со следующим кодом.

Возможно, вы уже заметили, что App\Models\Auth\User реализует контракт Illuminate\Contracts\Auth\Authenticatable.

Большинство методов, реализованных в нашем классе, говорят сами за себя. Мы определили метод fetchUserByCredentials, который вытягивает пользователя с back end. В нашем случае это будет класс MongoDatabase, именно к нему мы будем обращаться за необходимой информацией. Мы создали реализацию модели User.

Создание провайдера аутентификации

Мы уже говорили ранее, что система аутентификации Laravel состоит из двух элементов – Guard и провайдеры. В этом разделе мы создадим провайдер аутентификации, который будет вытягивать пользователя с back end. Создайте файл app/Extensions/MongoUserProvider.php, как показано ниже.

Необходимо, чтобы кастомный провайдер реализовывал контракт Illuminate\Contracts\Auth\UserProvider. Файл определяет два важных метода retrieveByCredentials и validateCredentials.

Метод retrieveByCredentials используется для получения данных авторизации пользователя через модель User, о которой мы говорили в предыдущем разделе. Метод validateCredentials проверяет пользователя по заданному набору данных.

Мы создали кастомный провайдер аутентификации. В следующем разделе мы перейдем к созданию Guard, который будет взаимодействовать с провайдером аутентификации MongoUserProvider.

Создание Guard аутентификации

Как мы уже говорили ранее, Guard в системе аутентификации Laravel определяет логику аутентификации пользователя. Мы будем проверять наличие параметра запроса jsondata. В нем должна быть JSON строка с данными авторизации.

В этом разделе мы создадим Guard, который будет общаться с провайдером аутентификации, созданном в предыдущем разделе. Создайте файл app/Services/Auth/JsonGuard.php со следующим кодом.

Прежде всего, нашему классу необходимо реализовывать интерфейс Illuminate\Contracts\Auth\Guard. Поэтому необходимо определить все методы, объявленные в интерфейсе.

Важно отметить тот факт, что функция __construct требует реализации Illuminate\Contracts\Auth\UserProvider. Мы передадим объект App\Extensions\MongoUserProvider.

Далее есть функция getJsonParams, получающая данные авторизации пользователя из параметра jsondata запроса. Ожидается строка JSON с данными авторизации пользователя, поэтому мы декодируем JSON данные с помощью функции json_decode.

В функции валидации первое, что мы проверяем – существование аргумента $credentials. Если его нет, вызывается метод getJsonParams для получения данных авторизации пользователя из параметров запроса.

Далее мы вызываем метод retrieveByCredentials провайдера MongoUserProvider, который получает пользователя из базы данных MongoDB с back end. И наконец, метод validateCredentials провайдера MongoUserProvider валидирует пользователя.

Это была реализация кастомного Guard. В следующем разделе говорится, как связать все эти части вместе и сформировать систему аутентификации.

Собираем все вместе

Мы разработали все элементы кастомного Guard аутентификации, которые должны дать нам новую систему аутентификации. Однако прямо вот так она не заработает. Ее необходимо зарегистрировать в привязках сервис контейнера Laravel.

Откройте файл app/Providers/AuthServiceProvider.php. С его помощью можно добавить привязки сервис контейнера аутентификации. Если в нем нет кастомных изменений, можете просто заменить код на код ниже.

Рассмотрим метод boot, в котором хранится большая часть привязок провайдера. Для начала создадим привязки для App\Database\MongoDatabase и App\Models\Auth\User.

Пришло время вставить наш кастомный Guard в систему аутентификации Laravel.

С помощью провайдер метода Auth Facade мы добавили наш кастомный провайдер аутентификации под ключ mongo. Вспоминайте, этот ключ отражает настройки, которые мы ранее вносили в файл auth.php.

Точно так же мы вставим наша реализацию кастомного Guard с помощью метода extend Auth façade.

Далее идет метод register, с помощью которого мы привязали интерфейс App\Services\Contracts\NosqlServiceInterface к реализации App\Database\MongoDatabase.

Теперь когда понадобится разрешить зависимость App\Services\Contracts\NosqlServiceInterface, Laravel ответит реализацией адаптера App\Database\MongoDatabase.

Преимущество этого подхода в том, что реализацию можно легко заменить на другую. Например, кто-то захотел заменить реализацию App\Database\MongoDatabase на адаптер CouchDB. Для этого ему необходимо лишь добавить соответствующую привязку в метод register.

Сервис провайдер в вашем распоряжении. Сейчас у нас есть все необходимое для тестирования кастомной реализации Guard. Остался раздел, подводящий итоги.

Это работает?

Вы проделали сложную работу по созданию своего первого кастомного Guard аутентификации. Пора попробовать его в действии. Быстро создадим простой файл контроллера app/Http/Controllers/MongoController.php.

Подробно разберем зависимость метода login, который требует реализацию Guard Illuminate\Contracts\Auth\Guard. В файле auth.php по умолчанию мы задали Guard custom, поэтому вставляться будем App\Services\Auth\JsonGuard!

Далее мы вызвали метод validate класса App\Services\Auth\JsonGuard, который запускает серию вызовов методов:

вызывается метод retrieveByCredentials класса App\Extensions\MongoUserProvider

метод retrieveByCredentials вызывает метод fetchUserByCredentials класса App\Models\Auth\User

метод fetchUserByCredentials вызывает метод find класса App\Database\MongoDatabase и получает данные авторизации пользователя

метод find класса App\Database\MongoDatabase возвращает ответ!

Если все отработает, как ожидается, мы должны получить аутентифицированного пользователя через вызов метода user нашего Guard.

Для доступа к контроллеру необходимо добавить соответствующий роут в файл routes/web.php.

Попробуйте открыть //your-laravel-site/custom/mongo/login, не передавая параметры. Должно отобразиться сообщение «not authorized».

Если открыть что-то типа //your-laravel-site/custom/mongo/login?jsondata={«username»:»admin»,»password»:»admin»}, должно вернуться успешное сообщение, если пользователь есть в базе данных.

Заметьте, что это лишь демонстрация возможностей кастомного Guard. Такие вещи, как логин, необходимо делать с защитой от дурака. Я же показал лишь общий взгляд на процесс аутентификации. Вы сами должны создать надежную и безопасную систему для своего приложения.

Наше приключение заканчивается, вскоре вернусь с новой полезной статьей, надеюсь. Хотите спросить что-то по какой-либо теме, пишите!

Заключение

Фреймворк Laravel предоставляет надежную систему аутентификации в ядре, которую можно расширить кастомной системой. Темой сегодняшней статьи стала реализация кастомного Guard и его вставка в процесс аутентификации Laravel.

В процессе мы разработали систему, аутентифицирующую пользователя по JSON в запросе и проверяющую эти данные с базой данных MongoDB. Для этого мы создали кастомный Guard и провайдер.

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

Автор: Sajal Soni

Источник: //code.tutsplus.com/

Редакция: Команда webformyself.

Метки:

Похожие статьи:

Комментарии Вконтакте: