Давайте снова посмотрим на новые возможности Laravel 5.2. В этой версии значительно доработана вся система авторизации, в том числе стало намного проще использовать сразу несколько «защитников».
Это одна из статей о новых функциях Laravel 5.2. Скоро будут ещё, не пропустите.
- Проверка массива формы в Laravel 5.2
- Неявная привязка модели маршрута в Laravel 5.2
- Ограничение скорости запросов API в Laravel 5.2
- Заготовка авторизации в Laravel 5.2
- Множественные драйверы защиты авторизации (включая API) в Laravel 5.2
Зачем вам это?
В Laravel до версии 5.2 защитником авторизации по умолчанию (который теперь называется web защитник) был обычный слой авторизации веб-приложения: имя и пароль передаются в контроллер, который проверяет их и выполняет перенаправление, когда они неверны, а когда верны — информация пользователя сохраняется в сессию. Не всегда точь в точь, но в целом это работало так.
А если вам нужен API, который должен работать в том же приложении и работать с JSON веб-токенами (или с каким-нибудь другим механизмом авторизации на основе отдельных запросов, а не сессии)? Раньше вам пришлось бы изрядно потрудиться, чтобы заставить работать сразу несколько драйверов авторизации.
Защитники авторизации по умолчанию в Laravel 5.2
В версии 5.2 заставить работать сразу несколько драйверов авторизации не то чтобы просто, здесь это работает прямо из коробки.
Если заглянуть в config/auth.php, то можно увидеть два набора защитников прямо из коробки: web — классический слой авторизации Laravel, и api — драйвер на основе токенов и отдельных запросов (не использующий память сессии).
Но, как видите, используется тот же «провайдер»:
Провайдеры авторизации тоже настраиваемы. Они определяют то, как система должна хранить и получать информацию о ваших пользователях. Каждый определяется как экземпляр Illuminate\Contracts\Auth\UserProvider.
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
А выше в config/auth.php видно, что защитником авторизации по умолчанию будет «web». Это значит, что при каждом использовании функций, посредников или фасадов авторизации в вашем приложении они по умолчанию будут обработаны защитником web, если вы явно не указали другое.
Знакомство с драйвером авторизации token
Итак, если web использует классический драйвер session, то что это за новый драйвер token, который используется в защитнике api?
Якоб Бэннет уже написал фантастическую статью о нём: Авторизация API Token в Laravel 5.2.
Прочитайте эту статью, чтобы подробно изучить работу драйвера, а мы рассмотрим его вкратце:
- Добавьте поле api_token в свою таблицу users. Строка длиной 60 символов, уникальная.
- В определении маршрутов вместо посредника auth используйте посредник auth:api.
- В маршрутах API используйте для получения пользователя
PHPAuth::guard('api')->user()
вместоPHPAuth::user()
.
Как видите, нам надо хранить api_token для каждого пользователя, и каждому входящему запросу, который проходит через защитника api на основе токенов, будет необходим параметр api_token с верным API-токеном для авторизации данного пользователя. А поскольку используются отдельные запросы, то каждый из них должен иметь этот API-токен. Один успешный запрос не значит, что следующий тоже будет успешен.
Авторизация на основе токенов работает так: подключающееся приложение (например, iOS-приложение) по запросу получит и сохранит токен для авторизации пользователя, и будет создавать API-вызовы, используя этот известный токен как часть URL. Например, если iOS-приложение захочет получить список друзей пользователя, то когда пользователь авторизуется в вашем приложении через веб-сайт/API, оно получит токен и сохранит его. И далее будет генерировать такие URL: http://yourapp.com/api/friends?api_token=СОХРАНЁННЫЙ_ТОКЕН_ТУТ
Использование драйверов не по умолчанию
Как вы заметили, в этом примере использования токенов два основных места, где мы будем использовать драйверы не по умолчанию: в посреднике защиты авторизации, и когда мы используем в коде такие удобные функции как PHPAuth::check()
и PHPAuth::user()
.
Вы можете указать защитника для своих маршрутов, добавив двоеточие и название защитника после PHPauth
в ключе посредника (например, PHPRoute::get('whatever', ['middleware' => 'auth:api'])
).
Вы можете указать защитника для ручного вызова в коде, сделав PHPguard('guardname')
первым вызовом в текучей цепочке при каждом использовании фасада Auth (например, PHPAuth::guard('api')->check()
).
Создание своих защитников и драйверов
Создавать своих защитников просто, потому что каждый защитник — просто ключ (web, api), указывающий на определённую конфигурацию драйвера (session, token) и провайдера (users). Они настраиваются в файле config/auth.php:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
'matts-fancy-api-guard' => [
'driver' => 'token',
'provider' => 'users',
],
],
Но вы можете возразить, что это не сильно повлияет на что-либо, пока вы не измените драйвер или провайдер.
Создать драйвер не так просто, как защитника. В документации есть раздел о создании своего драйвера авторизации, вам будет необходимо создать собственную реализацию Illuminate\Contracts\Auth\Guard, а затем зарегистрировать её в качестве драйвера где-нибудь в сервис-провайдере.
Также в документации описано как создать собственный провайдер пользователя.