Skip to content
Icon

ПРЕДУПРЕЖДЕНИЕ Вы просматриваете документацию к старой версии Laravel. Рассмотрите возможность обновления Вашего проекта до Laravel 9.x.

Аутентификация

Введение

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

По своей сути средства аутентификации Laravel состоят из «защитников» и «провайдеров». Защитники определяют, как пользователи аутентифицируются для каждого запроса. Например, Laravel поставляется с защитой сеанса `session, которая поддерживает состояние с помощью хранилища сеансов и файлов cookie.

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

Файл конфигурации аутентификации вашего приложения находится в config/auth.php. Этот файл содержит несколько хорошо задокументированных опций для настройки поведения служб аутентификации Laravel.

{tip} Защитников и провайдеров не следует путать с «ролями» и «разрешениями». Чтобы узнать больше об авторизации действий пользователя с помощью разрешений, обратитесь к документации авторизация.

Стартовые наборы

Хотите начать быстро? Установите стартовый комплект приложения Laravel в новое приложение Laravel. После переноса базы данных перейдите в браузере к /register или любому другому URL-адресу, назначенному вашему приложению. Стартовые комплекты позаботятся о создании всей вашей системы аутентификации!

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

Рекомендации по базе данных

По умолчанию Laravel включает App\Models\User модель Eloquent в каталоге app/Models. Эта модель может использоваться с драйвером аутентификации Eloquent по умолчанию. Если ваше приложение не использует Eloquent, вы можете использовать поставщика аутентификации database, который использует конструктор запросов Laravel.

При построении схемы базы данных для модели App\Models\User убедитесь, что длина столбца пароля не менее 60 символов. Конечно, миграция таблицы пользователей users, включенная в новые приложения Laravel, уже создает столбец, длина которого превышает эту.

Кроме того, вы должны убедиться, что ваша таблица users (или эквивалентная) содержит столбец remember_token, допускающий значение NULL, состоящий из 100 символов. Этот столбец будет использоваться для хранения токена для пользователей, выбравших опцию «запомнить меня» при входе в ваше приложение. Опять же, миграция таблицы пользователей users по умолчанию, включенная в новые приложения Laravel, уже содержит этот столбец.

Обзор экосистемы

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

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

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

Встроенные службы аутентификации браузера Laravel

Laravel включает в себя встроенные сервисы аутентификации и сеанса, доступ к которым обычно осуществляется через фасады Auth и Session. Эти функции обеспечивают аутентификацию на основе файлов cookie для запросов, инициированных веб-браузерами. Они предоставляют методы, позволяющие проверять учетные данные пользователя и аутентифицировать пользователя. Кроме того, эти службы будут автоматически сохранять надлежащие данные аутентификации в сеансе пользователя и выдавать файл cookie сеанса пользователя. Обсуждение того, как использовать эти сервисы, содержится в этой документации.

Стартовые наборы приложений

Как описано в этой документации, вы можете взаимодействовать с этими службами проверки подлинности вручную, чтобы создать собственный уровень проверки подлинности вашего приложения. Однако, чтобы помочь вам быстрее приступить к работе, мы выпустили бесплатные пакеты, которые обеспечивают надежную современную основу для всего уровня аутентификации. Это Laravel Breeze, Laravel Jetstream и Laravel Fortify.

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

Laravel Fortify — это серверная часть безголовой аутентификации для Laravel, которая реализует многие функции, описанные в этой документации, включая аутентификацию на основе файлов cookie, а также другие функции, такие как двухфакторная аутентификация и проверка электронной почты. Fortify предоставляет серверную часть аутентификации для Laravel Jetstream или может использоваться независимо в сочетании с Laravel Sanctum для обеспечения аутентификации для SPA, которому требуется аутентификация с помощью Laravel.

Laravel Jetstream — это надежный стартовый набор приложений, который использует и предоставляет службы аутентификации Laravel Fortify с красивым современным пользовательским интерфейсом на основе Tailwind CSS, Livewire, и/или Inertia.js. Laravel Jetstream включает дополнительную поддержку двухфакторной аутентификации, групповую поддержку, управление сеансами браузера, управление профилями и встроенную интеграцию с Laravel Sanctum для обеспечения аутентификации по токену API. Предложения Laravel по аутентификации API обсуждаются ниже.

Службы аутентификации Laravel API

Laravel предоставляет два дополнительных пакета, которые помогут вам в управлении токенами API и аутентификации запросов, сделанных с помощью токенов API: Passport и Sanctum. Обратите внимание, что эти библиотеки и встроенные в Laravel библиотеки аутентификации на основе файлов cookie не являются взаимоисключающими. Эти библиотеки в основном ориентированы на аутентификацию API-токенов, в то время как встроенные службы аутентификации ориентированы на аутентификацию браузера на основе файлов cookie. Многие приложения будут использовать как встроенные в Laravel службы аутентификации на основе файлов cookie, так и один из пакетов аутентификации Laravel API.

Passport

Passport — это поставщик аутентификации OAuth2, предлагающий различные «типы грантов» OAuth2, которые позволяют вам выпускать различные типы токенов. В общем, это надежный и сложный пакет для аутентификации API. Однако большинству приложений не требуются сложные функции, предлагаемые спецификацией OAuth2, что может сбивать с толку как пользователей, так и разработчиков. Кроме того, разработчики исторически не понимали, как аутентифицировать приложения SPA или мобильные приложения с помощью поставщиков аутентификации OAuth2, таких как Passport.

Sanctum

В ответ на сложность OAuth2 и замешательство разработчиков мы решили создать более простой и оптимизированный пакет проверки подлинности, который мог бы обрабатывать как собственные веб-запросы из веб-браузера, так и запросы API через токены. Эта цель была реализована с выпуском Laravel Sanctum, который следует считать предпочтительным и рекомендуемым пакетом аутентификации для приложений, которые будут предлагать собственный веб-интерфейс в дополнение к API или одностраничное приложение (SPA), существующее отдельно от серверного приложения Laravel, или приложения, предлагающие мобильный клиент.

Laravel Sanctum — это гибридный пакет веб-/API-аутентификации, который может управлять всем процессом аутентификации вашего приложения. Это возможно, потому что, когда приложения на основе Sanctum получают запрос, Sanctum сначала определяет, включает ли запрос файл cookie сеанса, который ссылается на аутентифицированный сеанс. Sanctum выполняет это, вызывая встроенные службы аутентификации Laravel, которые мы обсуждали ранее. Если запрос не аутентифицируется с помощью файла cookie сеанса, Sanctum проверит запрос на наличие токена API. Если присутствует токен API, Sanctum будет аутентифицировать запрос, используя этот токен. Чтобы узнать больше об этом процессе, обратитесь к документации Sanctum "как это работает".

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

Резюме и выбор стека

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

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

Если вы создаете одностраничное приложение (SPA), которое будет работать на бэкенде Laravel, вам следует использовать Laravel Sanctum. При использовании Sanctum вам потребуется либо вручную внедрить собственные внутренние маршруты аутентификации, либо использовать Laravel Fortify в качестве серверной службы безголовой аутентификации, которая обеспечивает маршруты и контроллеры для таких функций, как регистрация, сброс пароля, проверка электронной почты и многое другое.

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

И, если вы хотите быстро приступить к работе, мы рады порекомендовать Laravel Jetstream как быстрый способ запустить новое приложение Laravel, которое уже использует наш предпочтительный стек аутентификации Laravel. встроенные сервисы аутентификации и Laravel Sanctum.

Быстрое начало аутентификации

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

Установка стартового комплекта

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

Laravel Breeze — это минимальная и простая реализация всех функций аутентификации Laravel, включая вход в систему, регистрацию, сброс пароля, проверку электронной почты и подтверждение пароля. Слой представления Laravel Breeze состоит из простых шаблонов Blade, оформленных с помощью Tailwind CSS. Breeze также предлагает вариант создания каркаса на основе Inertia с использованием Vue или React.

Laravel Jetstream — это более надежный стартовый набор для приложений, который включает в себя поддержку создания каркаса вашего приложения с помощью Livewire или Inertia.js и Vue. Кроме того, Jetstream предлагает дополнительную поддержку двухфакторной аутентификации, групп, управление профилями, управление сеансами браузера, поддержку API через Laravel Sanctum, удаление учетной записи и многое другое.

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

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

use Illuminate\Support\Facades\Auth;
 
// Retrieve the currently authenticated user...
$user = Auth::user();
 
// Retrieve the currently authenticated user's ID...
$id = Auth::id();

В качестве альтернативы, как только пользователь аутентифицирован, вы можете получить доступ к аутентифицированному пользователю через экземпляр Illuminate\Http\Request. Помните, что классы с указанием типа будут автоматически внедряться в методы вашего контроллера. Указав тип объекта Illuminate\Http\Request, вы можете получить удобный доступ к аутентифицированному пользователю из любого метода контроллера в вашем приложении через метод запроса user:

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\Request;
 
class FlightController extends Controller
{
/**
* Update the flight information for an existing flight.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function update(Request $request)
{
// $request->user()
}
}

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

Чтобы определить, аутентифицирован ли пользователь, выполняющий входящий HTTP-запрос, вы можете использовать метод check на фасаде Auth. Этот метод вернет true, если пользователь аутентифицирован:

use Illuminate\Support\Facades\Auth;
 
if (Auth::check()) {
// The user is logged in...
}

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

Защита маршрутов

Мидлвар маршрута можно использовать, чтобы разрешить доступ к данному маршруту только пользователям, прошедшим проверку подлинности. Laravel поставляется с мидлваром auth, который ссылается на класс Illuminate\Auth\Middleware\Authenticate. Поскольку это мидлвар уже зарегистрирован в ядре HTTP вашего приложения, все, что вам нужно сделать, это прикрепить мидлвар к определению маршрута:

Route::get('/flights', function () {
// Only authenticated users may access this route...
})->middleware('auth');

Перенаправление неавторизованных пользователей

Когда мидлвар auth обнаружит неаутентифицированного пользователя, оно перенаправит пользователя на login именованный маршрут. Вы можете изменить это поведение, обновив функцию redirectTo в файле app/Http/Middleware/Authenticate.php вашего приложения:

/**
* Get the path the user should be redirected to.
*
* @param \Illuminate\Http\Request $request
* @return string
*/
protected function redirectTo($request)
{
return route('login');
}

Указание защиты

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

Route::get('/flights', function () {
// Only authenticated users may access this route...
})->middleware('auth:admin');

Вход в систему

Если вы используете Laravel Breeze или Laravel Jetstream стартовые наборы, к попыткам входа будет автоматически применяться ограничение скорости. По умолчанию пользователь не сможет войти в систему в течение одной минуты, если ему не удастся предоставить правильные учетные данные после нескольких попыток. Регулировка уникальна для имени пользователя/адреса электронной почты и их IP-адреса.

{tip} Если вы хотите ограничить скорость других маршрутов в своем приложении, ознакомьтесь с документацией по ограничению скорости.

Ручная аутентификация пользователей

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

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

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
 
class LoginController extends Controller
{
/**
* Handle an authentication attempt.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function authenticate(Request $request)
{
$credentials = $request->validate([
'email' => ['required', 'email'],
'password' => ['required'],
]);
 
if (Auth::attempt($credentials)) {
$request->session()->regenerate();
 
return redirect()->intended('dashboard');
}
 
return back()->withErrors([
'email' => 'The provided credentials do not match our records.',
]);
}
}

Метод attempt принимает в качестве первого аргумента массив пар ключ/значение. Значения в массиве будут использоваться для поиска пользователя в таблице вашей базы данных. Итак, в приведенном выше примере пользователь будет получен по значению столбца email. Если пользователь найден, хешированный пароль, хранящийся в базе данных, будет сравниваться со значением password, переданным в метод через массив. Вы не должны хэшировать значение пароля password входящего запроса, так как фреймворк автоматически хэширует значение, прежде чем сравнивать его с хешированным паролем в базе данных. Аутентифицированный сеанс будет запущен для пользователя, если два хешированных пароля совпадают.

Помните, что службы аутентификации Laravel будут извлекать пользователей из вашей базы данных на основе конфигурации «поставщика» вашей системы аутентификации. В файле конфигурации config/auth.php по умолчанию указан поставщик пользователей Eloquent, и ему предписывается использовать модель App\Models\User при получении пользователей. Вы можете изменить эти значения в файле конфигурации в зависимости от потребностей вашего приложения.

Метод attempt вернет true, если аутентификация прошла успешно. В противном случае будет возвращено false.

Метод intended, предоставляемый перенаправителем Laravel, перенаправит пользователя на URL-адрес, к которому он пытался получить доступ, прежде чем он будет перехвачен промежуточным программным обеспечением аутентификации. Этому методу может быть присвоен резервный URI на случай, если предполагаемый пункт назначения недоступен.

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

При желании вы также можете добавить дополнительные условия запроса к запросу аутентификации в дополнение к электронной почте и паролю пользователя. Для этого мы можем просто добавить условия запроса в массив, переданный методу attempt. Например, мы можем проверить, что пользователь помечен как «активный»:

if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
// Authentication was successful...
}

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

Доступ к определенным экземплярам Guard

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

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

if (Auth::guard('admin')->attempt($credentials)) {
// ...
}

Запоминание пользователей

Многие веб-приложения имеют флажок «запомнить меня» в своей форме входа. Если вы хотите обеспечить функциональность «запомнить меня» в своем приложении, вы можете передать логическое значение в качестве второго аргумента в метод attempt.

Когда это значение равно true, Laravel будет поддерживать аутентификацию пользователя на неопределенный срок или до тех пор, пока он не выйдет из системы вручную. Ваша таблица users должна включать строку remember_token, которая будет использоваться для хранения токена "запомнить меня". Миграция таблицы users, включенная в новые приложения Laravel, уже включает этот столбец:

use Illuminate\Support\Facades\Auth;
 
if (Auth::attempt(['email' => $email, 'password' => $password], $remember)) {
// The user is being remembered...
}

Другие методы аутентификации

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

Если вам нужно установить существующий экземпляр пользователя в качестве текущего аутентифицированного пользователя, вы можете передать экземпляр пользователя методу login фасада Auth. Данный пользовательский экземпляр должен быть реализацией Illuminate\Contracts\Auth\Authenticatable контракт. Модель App\Models\User, включенная в Laravel, уже реализует этот интерфейс. Этот метод аутентификации полезен, когда у вас уже есть действительный экземпляр пользователя, например, сразу после регистрации пользователя в вашем приложении:

use Illuminate\Support\Facades\Auth;
 
Auth::login($user);

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

Auth::login($user, $remember = true);

При необходимости вы можете указать защиту аутентификации перед вызовом метода login:

Auth::guard('admin')->login($user);

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

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

Auth::loginUsingId(1);

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

Auth::loginUsingId(1, $remember = true);

Authenticate A User Once

Вы можете использовать метод once для аутентификации пользователя с помощью приложения для одного запроса. При вызове этого метода не будут использоваться сеансы или файлы cookie:

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

Базовая HTTP-аутентификация

Базовая аутентификация HTTP обеспечивает быстрый способ аутентификации пользователей вашего приложения без создания специальной страницы входа. Чтобы начать работу, прикрепите auth.basic мидлвар к маршруту. Мидлвар auth.basic включен в структуру Laravel, поэтому вам не нужно его определять:

Route::get('/profile', function () {
// Only authenticated users may access this route...
})->middleware('auth.basic');

Как только мидлвар будет прикреплен к маршруту, вам автоматически будет предложено ввести учетные данные при доступе к маршруту в вашем браузере. По умолчанию мидлвар auth.basic предполагает, что столбец email в вашей таблице базы данных users является именем пользователя.

Примечание о FastCGI

Если вы используете PHP FastCGI и Apache для обслуживания своего приложения Laravel, базовая аутентификация HTTP может работать неправильно. Чтобы исправить эти проблемы, в файл .htaccess вашего приложения можно добавить следующие строки:

RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Базовая HTTP-аутентификация без сохранения состояния

Вы также можете использовать базовую HTTP-аутентификацию без установки файла cookie идентификатора пользователя в сеансе. Это в первую очередь полезно, если вы решите использовать HTTP-аутентификацию для аутентификации запросов к API вашего приложения. Для этого определить мидлвар, которое вызывает метод onceBasic. Если метод onceBasic не возвращает ответа, запрос может быть передан дальше в приложение:

<?php
 
namespace App\Http\Middleware;
 
use Illuminate\Support\Facades\Auth;
 
class AuthenticateOnceWithBasicAuth
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, $next)
{
return Auth::onceBasic() ?: $next($request);
}
 
}

Затем зарегистрируйте мидлвар маршрута и прикрепите его к маршруту:

Route::get('/api/user', function () {
// Only authenticated users may access this route...
})->middleware('auth.basic.once');

Выход

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

В дополнение к вызову метода logout рекомендуется аннулировать сеанс пользователя и повторно создать его токен CSRF. После выхода пользователя из системы вы обычно перенаправляете пользователя в корень вашего приложения:

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
 
/**
* Log the user out of the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function logout(Request $request)
{
Auth::logout();
 
$request->session()->invalidate();
 
$request->session()->regenerateToken();
 
return redirect('/');
}

Аннулирование сеансов на других устройствах

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

Прежде чем приступить к работе, вы должны убедиться, что мидлвар Illuminate\Session\Middleware\AuthenticateSession присутствует и не закомментировано в вашей веб-группе мидлваров App\Http\Kernel класса web:

'web' => [
// ...
\Illuminate\Session\Middleware\AuthenticateSession::class,
// ...
],

Затем вы можете использовать метод logoutOtherDevices, предоставляемый фасадом Auth. Этот метод требует, чтобы пользователь подтвердил свой текущий пароль, который ваше приложение должно принять через форму ввода:

use Illuminate\Support\Facades\Auth;
 
Auth::logoutOtherDevices($currentPassword);

Когда вызывается метод logoutOtherDevices, другие сеансы пользователя будут полностью аннулированы, что означает, что они будут "выведены из системы" из всех охранников, которые ранее аутентифицировали их.

Подтверждение пароля

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

{tip} В следующей документации обсуждается, как напрямую интегрироваться с функциями подтверждения пароля Laravel; однако, если вы хотите начать быстрее, стартовые наборы приложений Laravel включают поддержку этой функции!

Конфигурация

После подтверждения пароля пользователю не будет предложено повторно подтвердить пароль в течение трех часов. Однако вы можете настроить время, по истечении которого у пользователя будет повторно запрашиваться пароль, изменив значение параметра password_timeout в файле конфигурации config/auth.php вашего приложения.

Маршрутизация

Форма подтверждения пароля

Во-первых, мы определим маршрут для отображения представления, запрашивающего у пользователя подтверждение пароля:

Route::get('/confirm-password', function () {
return view('auth.confirm-password');
})->middleware('auth')->name('password.confirm');

Как и следовало ожидать, представление, возвращаемое этим маршрутом, должно иметь форму, содержащую поле password. Кроме того, не стесняйтесь включать в представление текст, объясняющий, что пользователь входит в защищенную область приложения и должен подтвердить свой пароль.

Подтверждение пароля

Далее мы определим маршрут, который будет обрабатывать запрос формы из представления «подтвердить пароль». Этот маршрут будет отвечать за проверку пароля и перенаправление пользователя по назначению:

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Redirect;
 
Route::post('/confirm-password', function (Request $request) {
if (! Hash::check($request->password, $request->user()->password)) {
return back()->withErrors([
'password' => ['The provided password does not match our records.']
]);
}
 
$request->session()->passwordConfirmed();
 
return redirect()->intended();
})->middleware(['auth', 'throttle:6,1']);

Прежде чем двигаться дальше, давайте рассмотрим этот маршрут более подробно. Во-первых, определяется, что поле пароля password запроса действительно соответствует паролю аутентифицированного пользователя. Если пароль действителен, нам нужно сообщить сеансу Laravel, что пользователь подтвердил свой пароль. Метод passwordConfirmed установит метку времени в сеансе пользователя, которую Laravel может использовать, чтобы определить, когда пользователь в последний раз подтверждал свой пароль. Наконец, мы можем перенаправить пользователя по назначению.

Защита маршрутов

Вы должны убедиться, что любому маршруту, который выполняет действие, требующее недавнего подтверждения пароля, назначен мидлвар password.confirm. Этот мидлвар включено в установку Laravel по умолчанию и автоматически сохраняет предполагаемое место назначения пользователя в сеансе, чтобы пользователь мог быть перенаправлен в это место после подтверждения своего пароля. После сохранения предполагаемого пункта назначения пользователя в сеансе мидлвар перенаправит пользователя на password.confirm именованный маршрут:

Route::get('/settings', function () {
// ...
})->middleware(['password.confirm']);
 
Route::post('/settings', function () {
// ...
})->middleware(['password.confirm']);

Добавление пользовательских защитников

Вы можете определить свои собственные средства защиты аутентификации, используя метод extend на фасаде Auth. Вы должны поместить вызов метода extend в сервис провайдер. Поскольку Laravel уже поставляется с AuthServiceProvider, мы можем разместить код в этом провайдере:

<?php
 
namespace App\Providers;
 
use App\Services\Auth\JwtGuard;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Auth;
 
class AuthServiceProvider extends ServiceProvider
{
/**
* Register any application authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
 
Auth::extend('jwt', function ($app, $name, array $config) {
// Return an instance of Illuminate\Contracts\Auth\Guard...
 
return new JwtGuard(Auth::createUserProvider($config['provider']));
});
}
}

Как вы можете видеть в приведенном выше примере, обратный вызов, переданный в метод extend, должен возвращать реализацию Illuminate\Contracts\Auth\Guard. Этот интерфейс содержит несколько методов, которые вам нужно будет реализовать, чтобы определить пользовательскую защиту. После того, как ваш собственный защитник был определен, вы можете ссылаться на него в конфигурации guards вашего конфигурационного файла auth.php:

'guards' => [
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],

Защитники замыкания запросов

Самый простой способ реализовать пользовательскую систему аутентификации на основе HTTP-запросов — использовать метод Auth::viaRequest. Этот метод позволяет быстро определить процесс аутентификации с помощью одного замыкания.

Для начала вызовите метод Auth::viaRequest внутри метода boot вашего AuthServiceProvider. Метод viaRequest принимает имя драйвера аутентификации в качестве первого аргумента. Это имя может быть любой строкой, описывающей вашу собственную защиту. Вторым аргументом, передаваемым методу, должно быть замыкание, которое получает входящий HTTP-запрос и возвращает экземпляр пользователя или, если аутентификация не удалась, null:

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
 
/**
* Register any application authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
 
Auth::viaRequest('custom-token', function (Request $request) {
return User::where('token', $request->token)->first();
});
}

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

'guards' => [
'api' => [
'driver' => 'custom-token',
],
],

Добавление пользовательских провайдеров пользователей

Если вы не используете традиционную реляционную базу данных для хранения своих пользователей, вам потребуется расширить Laravel с помощью собственного поставщика аутентификации пользователей. Мы будем использовать метод provider на фасаде Auth, чтобы определить пользовательского провайдера пользователя. Преобразователь провайдера пользователя должен вернуть реализацию Illuminate\Contracts\Auth\UserProvider:

<?php
 
namespace App\Providers;
 
use App\Extensions\MongoUserProvider;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Auth;
 
class AuthServiceProvider extends ServiceProvider
{
/**
* Register any application authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
 
Auth::provider('mongo', function ($app, array $config) {
// Return an instance of Illuminate\Contracts\Auth\UserProvider...
 
return new MongoUserProvider($app->make('mongo.connection'));
});
}
}

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

'providers' => [
'users' => [
'driver' => 'mongo',
],
],

Наконец, вы можете сослаться на этого провайдера в вашей конфигурации guards:

'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
],

Контракт провайдера пользователя

Реализации Illuminate\Contracts\Auth\UserProvider отвечают за получение реализации Illuminate\Contracts\Auth\Authenticatable из постоянной системы хранения, такой как MySQL, MongoDB и т. д. Эти два интерфейса позволяют механизмам аутентификации Laravel продолжать работу. работает независимо от того, как хранятся пользовательские данные или какой тип класса используется для представления аутентифицированного пользователя:

Давайте посмотрим на контракт Illuminate\Contracts\Auth\UserProvider:

<?php
 
namespace Illuminate\Contracts\Auth;
 
interface UserProvider
{
public function retrieveById($identifier);
public function retrieveByToken($identifier, $token);
public function updateRememberToken(Authenticatable $user, $token);
public function retrieveByCredentials(array $credentials);
public function validateCredentials(Authenticatable $user, array $credentials);
}

Функция retrieveById обычно получает ключ, представляющий пользователя, например автоматически увеличивающийся идентификатор из базы данных MySQL. Реализация Authenticatable, соответствующая идентификатору, должна быть получена и возвращена методом.

Функция retrieveByToken извлекает пользователя по его уникальному $identifier и "запомнить меня" $token, которые обычно хранятся в столбце базы данных, таком как remember_token. Как и в предыдущем методе, этот метод должен возвращать реализацию Authenticatable с совпадающим значением токена.

Метод updateRememberToken обновляет remember_token экземпляра $user новым токеном $token. Новый токен назначается пользователям при успешной попытке аутентификации «запомнить меня» или при выходе пользователя из системы.

Метод retrieveByCredentials получает массив учетных данных, переданных в метод Auth::attempt при попытке аутентификации в приложении. Затем метод должен «запросить» базовое постоянное хранилище для пользователя, соответствующего этим учетным данным. Как правило, этот метод запускает запрос с условием «где», который ищет запись пользователя с «именем пользователя», совпадающим со значением $credentials['username']. Метод должен возвращать реализацию Authenticatable. Этот метод не должен пытаться выполнить проверку пароля или аутентификацию.

Метод validateCredentials должен сравнить данный $user с $credentials для аутентификации пользователя. Например, этот метод обычно использует метод Hash::check для сравнения значения $user->getAuthPassword() со значением $credentials['password']. Этот метод должен возвращать true или false, указывающий, действителен ли пароль.

Аутентифицируемый контракт

Теперь, когда мы изучили каждый из методов UserProvider, давайте взглянем на контракт Authenticatable. Помните, что пользовательские провайдеры должны возвращать реализации этого интерфейса из методов retrieveById, retrieveByToken и retrieveByCredentials:

<?php
 
namespace Illuminate\Contracts\Auth;
 
interface Authenticatable
{
public function getAuthIdentifierName();
public function getAuthIdentifier();
public function getAuthPassword();
public function getRememberToken();
public function setRememberToken($value);
public function getRememberTokenName();
}

Этот интерфейс прост. Метод getAuthIdentifierName должен возвращать имя поля «первичный ключ» пользователя, а метод getAuthIdentifier должен возвращать «первичный ключ» пользователя. При использовании серверной части MySQL это, вероятно, будет автоматически увеличивающийся первичный ключ, назначенный записи пользователя. Метод getAuthPassword должен возвращать хешированный пароль пользователя.

Этот интерфейс позволяет системе аутентификации работать с любым «пользовательским» классом, независимо от того, какой уровень абстракции ORM или хранилища вы используете. По умолчанию Laravel включает класс App\Models\User в каталог app/Models, который реализует этот интерфейс.

События

Laravel отправляет множество событий во время процесса аутентификации. Вы можете прикрепить слушателей к этим событиям в своем EventServiceProvider:

/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
'Illuminate\Auth\Events\Registered' => [
'App\Listeners\LogRegisteredUser',
],
 
'Illuminate\Auth\Events\Attempting' => [
'App\Listeners\LogAuthenticationAttempt',
],
 
'Illuminate\Auth\Events\Authenticated' => [
'App\Listeners\LogAuthenticated',
],
 
'Illuminate\Auth\Events\Login' => [
'App\Listeners\LogSuccessfulLogin',
],
 
'Illuminate\Auth\Events\Failed' => [
'App\Listeners\LogFailedLogin',
],
 
'Illuminate\Auth\Events\Validated' => [
'App\Listeners\LogValidated',
],
 
'Illuminate\Auth\Events\Verified' => [
'App\Listeners\LogVerified',
],
 
'Illuminate\Auth\Events\Logout' => [
'App\Listeners\LogSuccessfulLogout',
],
 
'Illuminate\Auth\Events\CurrentDeviceLogout' => [
'App\Listeners\LogCurrentDeviceLogout',
],
 
'Illuminate\Auth\Events\OtherDeviceLogout' => [
'App\Listeners\LogOtherDeviceLogout',
],
 
'Illuminate\Auth\Events\Lockout' => [
'App\Listeners\LogLockout',
],
 
'Illuminate\Auth\Events\PasswordReset' => [
'App\Listeners\LogPasswordReset',
],
];