В этой статье я не буду показывать, как сделать форму аутентификации, но попытаюсь объяснить, как связаны все эти термины между собой. Разобравшись в этом, ты сможешь лучше понимать механизм аутентификации Laravel, а также сможешь создавать свои нестандартные решения.
Терминология
Итак, давай определим для начала, что означает Guard и Provider.
Guard Driver — это способ аутентификации пользователя при каждом запросе. Одним из стандартных драйверов guard-ов является session
— способ, при котором с помощью механизма php-сессий и cookies состояние пользователя восстанавливается при каждом запросе и система "опознает" таким образом пользователя, который совершает запрос.
User Provider — это способ, с помощью которого пользователи вытаскиваются из некоторого постоянного хранилища. В Laravel по-умолчанию предусмотрен способ с помощью моделей Eloquent и с помощью Database Query Builder (строителя запросов к базе данных). User Provider определяет драйвер модели (Eloquent или Database Query Builder) и дополнительные параметры, которые нужны для этого провайдера (например класс модели, или имя таблицы с пользователями). Каждый User Provider имеет свое уникальное имя (ключ), которое указывается в настройках Guard.
Guard — в рамках настроек Laravel это связка определенного guard-драйвера и user-провайдера, обозначенная уникальным именем (ключом), например web, admin, manager и так далее, и являет собой механизм аутентификации пользователя и хранения (или не хранения) состояния.
Классический пример: пользователей мы будем аутентифицировать и хранить в сессии, а самих пользователей будем доставать при помощи модели Eloquent.
Как мы выяснили выше, Guard-ов может быть несколько. Это нужно для того, чтобы создавать на сайте несколько областей, где требуется своя отдельная аутентификация.
Например, у нас есть личный кабинет пользователя и админка сайта. Пользователи личного кабинета и администраторы сайта хранятся в разных таблицах и мы не хотим, чтобы пользователи личного кабинета могли входить в админку при помощи своего логина и пароля. Для этого, как раз могут пригодиться два разных Guard-а, которым мы можем дать имена "web" и "admin" или "frontend" и "backend"
Пример (настройки, хранимые в файле конфигурации: config/auth.php):
...
//Guards
'guards' => [
//👇 ключ guard-а
'admin' => [
'driver' => 'session', //👈 Guard Driver
'provider' => 'admin_users', //👈 Ключ User Provider-а
],
//👇 ключ guard-а
'web' => [
'driver' => 'session', //👈 Guard Driver
'provider' => 'users', //👈 Ключ User Provider-а
],
],
...
//User providers
'providers' => [
'admin_users' => [
'driver' => 'eloquent', //👈 Provider Driver
'model' => Brackets\AdminAuth\Models\AdminUser::class, //👈 Класс модели
],
'users' => [
'driver' => 'database', //👈 Provider Driver
'table' => 'users', //👈 имя таблицы, в которой хранятся пользователи
],
],
Guard по-умолчанию
В рамках одного приложения, как ты заметил, может быть несколько guard-ов. Один из этих guard-ов можно назначить guard-ом по-умолчанию. То есть, если ты явно не будешь указывать, к какому из guard-ов ты обращаешься, будет использоваться guard по-умолчанию.
В настройках приложения, а именно в файле config/auth.php есть такая настройка:
...
'defaults' => [
'guard' => 'web', //👈 по-умолчанию используется guard 'web', который мы описали выше
...
],
...
AuthManager и фасад Auth
При помощи фасада Auth и класса AuthManager, в который ведет этот фасад, в Laravel мы можем осуществлять операции, связанные с аутентификацией пользователя: аутентифицировать с проверкой реквизитов (логин/пароль), аутентифицировать безусловно по id пользователя, "разлогинивать" пользователя и так далее.
Слабая связанность и абстракция
Чтобы AuthManager мог абстрагироваться от конкретной реализации вашей модели пользователей и от того, каким классом представлен User Provider, на помощь приходят контракты (интерфейсы):
- Illuminate\Contracts\Auth\UserProvider
- Illuminate\Contracts\Auth\Authenticatable
Первый позволяет абстрагироваться от конкретной реализации того, каким именно способом мы будем вытаскивать пользователей из постоянного хранилища (как пример, базы данных).
Второй позволяет абстрагироваться от класса модели пользователя.
Все, что вам нужно, чтобы реализовать какую-либо свою, нестандартную логику — это реализовать методы данных интерфейсов в соответствующих своих классах.
По-умолчанию, модель пользователя App\Models\User, которая идет в Laravel "из коробки" уже реализует интерфейс Authenticatable неявным образом через наследуемый класс Illuminate\Foundation\Auth\User:
<?php
namespace App\Models;
...
use Illuminate\Foundation\Auth\User as Authenticatable;
//обратите внимание на этот 👇 класс
class User extends Authenticatable {
...
}
А вот внутри класса Illuminate\Foundation\Auth\User уже реализован упомянутый выше интерфейс (контракт).
Как аутентифицировать пользователя
Аутентификация с проверкой реквизитов с использованием guard по-умолчанию
Метод attempt вернет true и аутентифицирует пользователя в случае, если указан корректный email и пароль и false — в ином случае.
Auth::attempt(['email' => 'blabla@email.com', 'password' => 'myVeryStrongPassword']);
Аутентификация с проверкой реквизитов с явным указанием guard
Auth::guard('admin')->attempt(['email' => 'blabla@email.com', 'password' => 'myVeryStrongPassword']);
Безусловная аутентификация по id
В отличие от метода attempt, данный метод ничего не возвращает, и просто успешно аутентифицирует пользователя с id = 5
Auth::loginUsingId(5);
Безусловная аутентификация по id с указанием guard и запоминанием в сессии
Auth::guard('admin')->loginUsingId(5, true);
Работа с аутентифицированным пользователем
После того, как мы аутентифицировали пользователя, мы можем обращаться к методу Auth::user()
или Auth::guard('имя_guard-a')->user()
, чтобы получить доступ к объекту пользователя, который в данный момент работает с приложением.
Условное отображение блоков в зависимости от аутентифицированности пользователя в шаблонах blade
<strong>Этот контент виден всем</strong>
@auth
<strong>Этот контент виден только пользователям аутентифированным в guard-е по-умолчанию</strong>
@endauth
@auth('admin')
<strong>Этот контент виден только пользователям аутентифированным в guard-е admin</strong>
@endauth
Заключение
Уверен, что теперь ты стал лучше понимать, как работает механизм аутентификации в Laravel, а если вдруг чего-то не понял, задавай вопросы в комментариях или в нашем telegram-чате
Вы должны авторизоваться, чтобы оставлять комментарии.