Аутентификация (Laravel 5.2) — Laravel Framework Russian Community

Rbac / abac

Немного теории и примеров. Вам скорее всего известна аббревиатура RBAC или по другому Role Bases Access Control. Это система разграничения прав доступа основанная на ролях. В ларавель достаточно просто реализовать RBAC, на вход в нашу функцию из гейта или политики приходит текущий пользователь ( инстанс модели по необходимости).

Реализация с ролями не сложная, но возможно будет правильнее проверять не роль пользователя, а доступ пользователя на совершение конкретного действия. То есть использовать ABAC модель доступа или по другому Attribute Based Access Control. Разграничение доступа на основе атрибутов. Модель ABAC так же отлично ложится на штатную систему авторизации ларавел.

Вот ссылка на статью с пояснениями по RBAC и ABAC. На практике у вас скорее всего будет какой то микс из этих моделей доступа. Пользователю при старте выдается какая либо роль или несколько ролей (к которым привязаны возможности), и далее доступ к конкретным действиям проверяется уже по отдельным возможностям роли (не просто по принадлежности пользователя к роли), плюс уточняется динамическими сравнениями и вычислениями.

Авторизация

Авторизация (authorization) в ларавел это процесс проверки какой то конкретной возможности, доступности какого либо действия для пользователя. Authorization дословно переводится с английского как «разрешение». Действие которое мы разрешаем может быть абсолютно любым, например может ли пользователь поливать цветы.

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

Если подходить ближе к практическим примерам, то реальной «возможностью» может быть например «возможность создания статьи». Вам в контроллер прилетает POST запрос, в котором лежит содержимое статьи, и в ответ на этот запрос вам нужно добавить статью и послать «ок», либо ответить ошибкой «доступ запрещен».

Похожее:  Подключение Debian GNU/Linux 8.6 к домену Active Directory с помощью SSSD и realmd - Блог IT-KB

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

Авторизация и аутентификация

Первое что нужно понять — различие между авторизацией (authorization) и аутентификацией (authentication). Звучит довольно похоже, но на самом деле это разные вещи. И не только в laravel.

Аутентификация пользователя по id

Для входа пользователя в приложение по его ID, используйте метод loginUsingId. Этот метод просто принимает первичный ключ пользователя, которого необходимо аутентифицировать:

Auth::loginUsingId(1);
Auth::loginUsingId(1, true);

В чем различия?

Но зачем тогда вообще вводить две разные сущности? По большей части это вопрос удобства. Главное что нужно понимать, в каких случаях вызывается гейт, а в каких функция из класса политики. Зная этот механизм вы в каждом конкретном случае выберите для себя наиболее подходящий вариант.

Если объявить сразу и гейт и политику с одинаковым именем, как например мы сделали выше в случае с post_create, то какую именно функцию выполнит laravel?

Всё достаточно просто, если вторым аргументом мы передаем какой-либо класс (или инстанс класса), и для этого класса зарегистрирована политика с нужной функцией, то вызовется именно функция из класса политики. Если же мы ничего не будем передавать вторым аргументом, то вызовется функция объявленная гейтом.

// будет вызвана функция из класса политики (если функция post_create существует)
$this->authorize('post_create', Article::class);
// будет вызвана функция из гейта
$this->authorize('post_create');

Отсюда следует вывод, что политики удобнее в случае когда нужно сгруппировать какие либо проверки авторизации. Не обязательно это кстати говоря должна быть группировка по модели. Если у нас есть группа каких-то схожих возможностей (доступных пользователю действий), то проще выделить их в отдельный класс и сложить в одном месте.

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

И гейты и политики вы определяете самостоятельно. Названия view, create, update и т.д. которые встречаются в примерах ничем не отличаются от проверки «water-flowers» (поливка цветов). Название у функции авторизации может быть абсолютно любое.

Завершение сессии

Для завершения сессии пользователя можно использовать метод logout фасада Auth. Он очистит информацию об аутентификации в сессии пользователя:

Auth::logout();

Изменение пути

Когда пользователь успешно аутентифицируется, он будет перенаправлен на URI /home. Вы можете изменить место для перенаправления после входа, задав свойство redirectTo контроллеров LoginController, RegisterController и ResetPasswordController:

protected $redirectTo = '/';

Если для пути перенаправления требуется собственная логика генерации, можно задать метод redirectTo вместо свойства redirectTo:

protectedfunctionredirectTo(){ return'/path';
}

Метод redirectTo имеет приоритет над атрибутом redirectTo.

Модель и таблица

Большинство веб-приложения позволяют пользователям сбросить забытый пароль. Вместо того, чтобы каждый раз изобретать велосипед, Laravel предоставляет удобный механизм для реализации этой возможности.

Назначение гарда

Когда вы назначаете middleware auth для защиты роута, вы можете явно указать, какой guard из тех, что определены у вас в config/auth.php вы хотите использовать в данном случае:

Route::get('profile', [ 'middleware' => 'auth:api', 'uses' => 'ProfileController@show']);

Настройка валидации и сохранения пользователей

Для изменения полей формы, обязательных к заполнению при регистрации пользователей, или для изменения способа создания пользователей в базе данных вы можете править класс AuthController. Этот класс отвечает за валидацию и создание новых пользователей вашего приложения.

Метод validator класса AuthController содержит в себе правила валидации формы регистрации новых пользователей. Вы можете изменять его, как пожелаете.

Настройка гардов

В config/auth.php вы можете определить несколько гардов. Чтобы использовать выбранный гард для процедуры восстановления пароля, добавьте свойство в класс PasswordController:

Настройка гардов (guards)

Вы также можете назначить специфичный гард для обработки процесса аутентификации. Для этого создайте свойство guard в вашем классе AuthController. Значением этого свойства должно быть название одного из гардов, определённых вами в файле config/auth.php.

Настройка гварда

Вы также можете изменить «гварда», который используется для аутентификации и регистрации пользователей. Для начала задайте метод guard в LoginController, RegisterController и ResetPasswordController. Метод должен возвращать экземпляр гварда:

useIlluminateSupportFacadesAuth;protectedfunctionguard(){ return Auth::guard('guard-name');
}

Обращение к конкретным экземплярам гварда

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

Передаваемое в метод guard имя гварда должно соответствовать одному из защитников, настроенных в конфиге auth.php:

Однократная аутентификация пользователя

Вы также можете использовать метод once для пользовательского входа в систему для одного запроса. Сеансы и cookies не будут использоваться, что может быть полезно при создании API без сохранения состояний:

if (Auth::once($credentials)) {
}

Определение, аутентифицирован ли пользователь

Чтобы определить, что пользователь уже вошёл в ваше приложение, вы можете использовать метод check фасада Auth, который вернёт true, если пользователь аутентифицирован:

useIlluminateSupportFacadesAuth;if (Auth::check()) {
}

Хотя и возможно определить аутентифицирован ли пользователь, используя метод check, обычно вы будете использовать посредников для проверки был ли пользователь аутентифицирован ранее, позволяя этому пользователю получать доступ к определенным роутам / контроллерам. Для получения дополнительной информации смотрите документацию о защите роутов.

Пакеты composer для авторизации

Система авторизации в коде подходит только для каких то простых случаев. Для более сложных потребуется хранение информации по ролям, атрибутам, возможностям и т.д. в базе данных. Для laravel есть несколько готовых composer пакетов, которые реализуют этот функционал.

Нужно понимать что эти пакеты просто дают возможность хранения доступов в БД, все запросы с учетом нужных сохраненных прав вам придется строить самостоятельно. Пакеты регистрируют свою функцию, которую вызовет ларавел при проверке авторизации, в тот момент когда вы проверяете $this->authorize(…) в контроллере, на самом деле выполняется какая то функция из конкретного пакета.

Политики и гейты

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

В одном случае, чтобы создать гейт мы объявляем функцию проверки так:

Проверка прав пользователя без аутентификации

Метод validate позволяет проверить права пользователя без фактической аутентификации:

if (Auth::validate($credentials))
{
}

Создание миграции для таблицы с напоминаниями паролей

Далее нужно создать таблицу, хранящую токены-напоминания для сброса пароля. Эта миграция уже включена в Laravel и находится в папке database/migrations. Поэтому всё, что вам нужно сделать, это выполнить команду:

php artisan migrate

Создание миграции таблицы токенов сброса паролей

Дальше вам необходимо создать таблицу, в которой будут храниться токены сброса паролей. Эта миграция по умолчанию уже включена в Laravel в каталог database/migrations. Поэтому вам остаётся только мигрировать базу данных:

php artisan migrate

Laravel предоставляет класс AuthPasswordController, в котором содержится вся необходимая логика для сброса паролей. Для создания роутов и шаблонов вам нужно воспользоваться командой:

php artisan make:auth

Эта же команда создает в папке resources/views/auth/passwords шаблоны для страниц восстановления пароля.

После того, как вы определили роуты и шаблоны для сброса паролей, можете проверить их в браузере, пройдя по урлу /password/reset. Класс PasswordController включён в фреймворк по умолчанию и содержит всю необходимую логику для отправки писем и сброса паролей в базе данных.

После сброса пароля пользователь автоматически аутентифицируется в вашем приложении и редиректится на страницу /home. Вы можете изменить этот путь, создав свойство redirectTo у PasswordController

protected $redirectTo = '/dashboard';

Обратите внимание: По умолчанию токен сброса пароля существует 1 час. Вы можете изменить это в конфигурационном файле config/auth.php с помощью опции expire.

Указание гварда

Во время прикрепления посредника auth к роуту, вы можете также указать, какой гвард должен быть использован для выполнения аутентификации. Указанный гвард должен соответствовать одному из ключей в массиве guards вашего конфига auth.php:

publicfunction__construct(){ $this->middleware('auth:api');
}

Если вы используете встроенный в Laravel класс LoginController, трейт IlluminateFoundationAuthThrottlesLogins уже будет включён в ваш контроллер. По умолчанию пользователь не сможет войти в приложение в течение одной минуты, если он несколько раз указал неправильные данные для входа. Ограничение происходит отдельно для имени пользователя/адреса e-mail и его IP-адреса.

Конечно, совсем не обязательно использовать контроллеры аутентификации, включенные в Laravel. Если вы захотите убрать эти контроллеры, вам нужно будет напрямую управлять аутентификацией пользователей, используя классы аутентификации Laravel. Не волнуйтесь, они не кусаются!

Мы будем работать со службами аутентификации Laravel через фасадAuth, поэтому нам надо не забыть импортировать фасад Auth в начале класса. Далее давайте посмотрим на метод attempt:

Указание дополнительных условий

При необходимости вы можете добавить дополнительные условия к запросу аутентификации, помимо адреса e-mail и пароля. Например, можно проверить отметку «активности» пользователя:

if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
}

Итого

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

Можете так же посмотреть дополнительные статьи по теме:

Надеюсь статья оказалась вам полезной, если это действительно так, то можете сказать спасибо в комментариях 🙂