Версія фреймворка: 8.x

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

Вступ

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

По суті, засоби автентифікації Laravel складаються з "охоронців" (guards) та "постачальників"(providers). Охоронці визначають спосіб автентифікації користувачів для кожного запиту. Наприклад, Laravel постачається із захистом session, який підтримує стан за допомогою сховища сесій (session storage) та файлів cookie.

Постачальники визначають спосіб отримання користувачів із вашого постійного сховища. Laravel постачається з підтримкою отримання користувачів за допомогою [Eloquent](/ docs / 8.x / eloquent) та конструктора запитів до бази даних. Тим не менш, ви можете визначити додаткових постачальників, які потрібні для вашої програми.

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

Стартові набори

Хочете швидко розпочати? Встановіть Laravel application starter kit у свіжому додатку Laravel. Після міграції бази даних перейдіть у браузері в /register або будь-яку іншу URL-адресу, призначену вашій програмі. Jetstream подбає про побудову всієї вашої системи автентифікації!

Навіть якщо ви вирішите не використовувати стартовий набір у остаточному додатку Laravel, встановлення стартового набору Laravel Breeze може стати чудовою можливістю дізнайтися як реалізувати всі функції автентифікації Laravel у реальному проекті Laravel. Оскільки Laravel Breeze створює для вас контролери автентифікації, маршрути та подання, ви можете вивчити код у цих файлах, щоб дізнатися, як можуть бути реалізовані функції автентифікації Laravel.

Зауваження щодо бази даних

За замовчуванням Laravel включає App\Models\UserEloquent модель у ваш каталог app/Models. Цю модель можна використовувати із драйвером автентифікації Eloquent за замовчуванням. Якщо у вашій програмі не використовується Eloquent, ви можете використовувати database драйвер автентифікації, який використовує конструктор запитів Laravel.

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

Крім того, слід перевірити, що ваша users (або еквівалентна) таблиця містить стовпець remember_token не меньше чим на 100 символів. Цей стовпець буде використовуватися для зберігання токена користувачів, які при вході у програму вибирають опцію "запам'ятати мене".

Огляд екосистеми

Laravel пропонує кілька пакетів, пов’язаних з аутентифікацією. Перш ніж продовжувати, ми розглянемо загальну екосистему автентифікації в Laravel та обговоримо цільове призначення кожного пакета.

Спочатку розглянемо, як працює автентифікація. Під час використання веб-браузера користувач надає своє ім’я користувача та пароль через форму входу. Якщо ці облікові дані є правильними, програма зберігатиме інформацію про автентифікованого користувача в session. Файл cookie, виданий браузеру, містить ID сесії, щоб подальші запити до програми могли асоціювати користувача з правильною сесією. Після отримання файлу cookie сесії програма отримає дані сесії на основі ID сеансу. Pауважимо, що інформація про аутентифікацію зберігалася в сеансі, і буде вважати користувача "автентифікованим".

Коли для доступу до API віддаленій службі потрібно пройти автентифікацію, файли cookie зазвичай не використовуються, оскільки немає веб-браузера. Натомість віддалена служба надсилає токен API до API на кожен запит. Додаток може перевірити вхідний токен за таблицею дійсних токенів API та "аутентифікувати" запит, який виконується користувачем, пов'язаним із цим токеном API.

Вбудовані служби автентифікації браузера у Laravel

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

Стартові набори програми

Як обговорюється в цій документації, ви можете взаємодіяти з цими службами автентифікації вручну, щоб створити власний рівень автентифікації вашої програми. Однак, щоб допомогти вам швидше розпочати роботу, ми випустили безкоштовні пакети, що забезпечують надійне, сучасне формування всього рівня аутентифікації. Цими пакетами є Laravel Jetstream та Laravel Fortify.

Laravel Breeze це проста, мінімальна реалізація всіх функцій автентифікації Laravel, включаючи вхід, реєстрацію, скидання пароля, перевірку електронної пошти та підтвердження пароля. У Laravel Breeze представлення складається з простих Blade templates стилізованих за допомогою Tailwind CSS. Щоб почати, перегляньте документацію Laravel application starter kits.

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.Пропозиції автентифікації API Laravel розглядаються нижче.

Служби автентифікації API Laravel

Laravel пропонує два опціональні пакети, які допоможуть вам в управлінні токенами API та аутентифікації запитів, зроблених за допомогою токенів API: Passport таSanctum. Зверніть увагу, що ці бібліотеки та вбудовані бібліотеки автентифікації на основі файлів cookie Laravel не є взаємовиключними. Ці бібліотеки головним чином зосереджуються на автентифікації токена API, тоді як вбудовані служби автентифікації фокусуються на аутентифікації браузера на основі файлів cookie. Багато програм використовуватимуть як вбудовані служби автентифікації на основі файлів cookie, так і один із пакетів автентифікації API Laravel.

Passport

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

Sanctum

У відповідь на складність OAuth2 та плутанину розробників ми вирішили створити простіший, спрощений пакет автентифікації, який міг би обробляти як власні веб-запити з веб-браузера, так і запити API через токени. Ця мета була реалізована з виходомLaravel Sanctum, який слід вважати кращим та рекомендованим пакетом автентифікації для додатків, які пропонують власний веб-інтерфейс на додаток до API, або забезпечуватимуться односторінковою програмою, яка існує окремо від внутрішньої програми Laravel або додатків які пропонують мобільний клієнт.

Laravel Sanctum - це гібридний пакет аутентифікації через Інтернет / API, який може керувати всім процесом автентифікації вашої програми. Це можливо, оскільки коли програми, засновані на Sanctum, отримують запит, Sanctum спочатку визначає, чи включає запит сеансовий файл cookie, який посилається на аутентифіковану сесію. Sanctum досягає цього за допомогою виклику вбудованих служб автентифікації Laravel, про які ми вже говорили раніше. Якщо запит не аутентифікується за допомогою сеансового файлу cookie, Sanctum перевірить запит на токен API. Якщо присутній токен API, Sanctum автентифікує запит за допомогою цього токену. Щоб дізнатися більше про цей процес, зверніться до документації Sanctum "how it works".

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

Підсумок та вибір вашого стека

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

Далі, якщо ваша програма пропонує API, ви можете вибрати між нимиПаспортабоСвятинядля забезпечення автентифікації маркера API для вашої програми. Загалом, Sanctum слід віддавати перевагу, коли це можливо, оскільки це просте, повне рішення для автентифікації API, аутентифікації SPA та мобільної автентифікації, що включає підтримку "обсягу" або "можливостей".

Паспорт можна вибрати, коли вашій програмі абсолютно потрібні всі функції, передбачені специфікацією OAuth2.

І якщо ви хочете швидко розпочати роботу, ми раді порадитиLaravel Jetstreamяк швидкий спосіб запустити нову програму Laravel, яка вже використовує бажаний стек автентифікації вбудованих служб автентифікації Laravel та Laravel Sanctum.

Швидкий старт автентифікації

У цій частині документації обговорюється аутентифікація користувачів черезLaravel Jetstreamпакет, який включає будівельні ліси для інтерфейсу, щоб допомогти вам швидко розпочати роботу. Якщо ви хочете безпосередньо інтегруватися із системами автентифікації Laravel, ознайомтеся з документацією наавтентифікація користувачів вручну.

Routing

Laravellaravel/jetstreamЦей пакет забезпечує швидкий спосіб побудови всіх всіх маршрутів, переглядів та іншої логіки сервера, необхідних для автентифікації, за допомогою декількох простих команд:

composer require laravel/jetstream

// Install Jetstream with the Livewire stack...
php artisan jetstream:install livewire

// Install Jetstream with the Inertia stack...
php artisan jetstream:install inertia

Цю команду слід використовувати у нових програмах та встановлюватиме вигляд макета, View реєстрації та входу, а також маршрути для всіх кінцевих точок автентифікації. A/dashboardМаршрут також буде створений для обробки запитів після входу в систему на інформаційну панель вашої програми.

Створення додатків, включаючи автентифікацію

Якщо ви запускаєте нову програму і хочете включити риштування для автентифікації, ви можете використовувати--jetпри створенні програми за допомогою програми Laravel Installer. Ця команда створить нову програму з усіма складеними та встановленими лісами автентифікації:

laravel new kitetail --jet
Щоб дізнатись більше про Jetstream, відвідайте офіційного представникаДокументація Jetstream.

Перегляди

Як зазначалося в попередньому розділі,laravel/jetstreamпакетphp artisan jetstream:installкоманда створить усі View, необхідні для автентифікації, та розмістить їх уresources/views/authкаталог.

Jetstream також створить aresources/views/layoutsкаталог, що містить базовий макет для вашої програми. Усі ці погляди використовуютьCSS вітру хвостаFramework, але ви можете налаштувати їх як завгодно.

Автентифікація

Тепер, коли вашу програму було створено для проведення автентифікації, ви готові зареєструватися та автентифікуватися! Ви можете просто отримати доступ до своєї програми у браузері, оскільки контролери автентифікації Jetstream вже містять логіку для автентифікації існуючих користувачів та зберігання нових користувачів у базі даних.

Налаштування контуру

Коли користувач успішно аутентифікується, він, як правило, перенаправляється на/homeURI. Ви можете налаштувати шлях перенаправлення після автентифікації, використовуючиHOMEконстанта, визначена у вашомуRouteServiceProvider:

public const HOME = '/home';

При використанні Laravel Jetstream процес встановлення Jetstream змінить значенняHOMEконстанта до/dashboard.

Отримання автентифікованого користувача

Під час обробки вхідного запиту ви можете отримати доступ до аутентифікованого користувача черезAuthфасад:

use Illuminate\Support\Facades\Auth;

// Get the currently authenticated user...
$user = Auth::user();

// Get the currently authenticated user's ID...
$id = Auth::id();

Як варіант, як тільки аутентифікація користувача, ви можете отримати доступ до аутентифікованого користувача черезIlluminate\Http\Requestінстанції. Пам'ятайте, підказкові класи автоматично вводитимуться у ваші методи контролера. За допомогою натякування типуIlluminate\Http\Requestоб'єкт, ви можете отримати зручний доступ до аутентифікованого користувача за допомогою будь-якого методу контролера у вашій програмі:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class FlightController extends Controller
{
    /**
     * Get a list of all available flights.
     *
     * @param  Request  $request
     * @return Response
     */
    public function update(Request $request)
    {
        // $request->user() returns an instance of the authenticated user...
    }
}

Визначення автентифікації поточного користувача

Щоб визначити, чи користувач вже ввійшов у вашу програму, ви можете використовуватиcheckметод наAuthфасад, який повернетьсяtrueякщо аутентифікація користувача:

use Illuminate\Support\Facades\Auth;

if (Auth::check()) {
    // The user is logged in...
}
Незважаючи на те, що можна визначити, чи аутентифіковано користувача за допомогоюcheckметодом, ви зазвичай використовуєте Middleware для перевірки автентичності користувача, перш ніж надавати користувачеві доступ до певних маршрутів / контролерів. Щоб дізнатись більше про це, перегляньте документацію наохоронні маршрути.

Захист маршрутів

Маршрутизуйте Middlewareможе використовуватися, щоб дозволити лише аутентифікованим користувачам доступ до заданого маршруту. Laravel кораблі зauthMiddleware, яке посилається наIlluminate\Auth\Middleware\Authenticateклас. Оскільки це Middleware вже зареєстроване у вашому ядрі HTTP, все, що вам потрібно зробити, це приєднати Middleware до визначення маршруту:

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

Перенаправлення неавторизованих користувачів

КолиauthMiddleware виявляє неавторизованого користувача, воно перенаправляє користувача на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 enter...
})->middleware('auth:api');

Ввімкнення дроселювання

Якщо ви використовуєте Laravel Jetstream, обмеження швидкості автоматично застосовуватиметься до спроб входу. За замовчуванням користувач не зможе увійти в систему протягом однієї хвилини, якщо після декількох спроб не зможе надати правильні дані. Регулювання є унікальним для імені користувача / електронної адреси користувача та його IP-адреси.

Якщо ви хочете оцінити обмеження власних маршрутів, перегляньтедокументація, що обмежує норму.

Автентифікація користувачів вручну

Вам не потрібно використовувати риштування для автентифікації, що входить до складу Laravel Jetstream. Якщо ви вирішите не використовувати цей риштування, вам потрібно буде керувати автентифікацією користувачів за допомогою класів автентифікації Laravel безпосередньо. Не хвилюйся, це суть!

Ми отримаємо доступ до послуг автентифікації Laravel черезAuthфасад, тому нам потрібно переконатися, що імпортуємо файлAuthFacadeу верхній частині класу. Далі, давайте перевіримо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 Response
     */
    public function authenticate(Request $request)
    {
        $credentials = $request->only('email', 'password');

        if (Auth::attempt($credentials)) {
            // Authentication passed...
            return redirect()->intended('dashboard');
        }
    }
}

attemptметод приймає масив пар ключ / значення як перший аргумент. Значення масиву будуть використані для пошуку користувача в таблиці бази даних. Отже, у наведеному вище прикладі користувач отримає значенняemailстовпець. Якщо користувача знайдено, хешований пароль, що зберігається в базі даних, буде порівняно зpasswordзначення, передане методу через масив. Не слід хешувати пароль, зазначений якpasswordvalue, оскільки фреймворк автоматично хешує значення перед порівнянням із хешованим паролем у базі даних. Якщо два хешовані паролі збігаються, для користувача буде запущено аутентифікований сеанс.

attemptметод повернетьсяtrueякщо автентифікація була успішною. В іншому випадкуfalseбуде повернено.

intendedна редиректорі перенаправить користувача на URL-адресу, до якої він намагався отримати доступ, перш ніж перехопити Middleware для автентифікації. Цей метод може бути наданий резервний URI, якщо передбачуваний пункт призначення недоступний.

Вказівка ​​додаткових умов

За бажанням ви можете також додати додаткові умови до запиту автентифікації на додаток до електронної пошти та пароля користувача. Наприклад, ми можемо перевірити, що користувач позначений як "активний":

if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
    // The user is active, not suspended, and exists.
}
У цих прикладахemailне є обов’язковим варіантом, він просто використовується як приклад. Ви повинні використовувати будь-яке ім'я стовпця, яке відповідає "імені користувача" у вашій базі даних.

Доступ до конкретних екземплярів Guard

Ви можете вказати, який екземпляр охорони ви хочете використовувати, використовуючиguardметод наAuthфасад. Це дозволяє керувати аутентифікацією для окремих частин вашого додатка, використовуючи повністю окремі моделі, що піддаються автентифікації, або таблиці користувачів.

Ім'я охоронця перейшло доguardметод повинен відповідати одному із охоронців, налаштованих у вашомуauth.phpфайл конфігурації:

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

Вихід

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

Auth::logout();

Запам'ятовування користувачів

Якщо ви хочете надати у своїй програмі функціональність "запам'ятати мене", ви можете передати булеве значення як другий аргументattemptметод, який зберігатиме автентифікацію користувача необмежений час або до виходу з нього вручну. Вашusersтаблиця повинна містити рядокremember_tokenстовпець, який буде використовуватися для зберігання маркера "запам'ятати мене".

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

Якщо ви "пам'ятаєте" користувачів, ви можете використовуватиviaRememberспосіб визначити, чи аутентифіковано користувача за допомогою файлу cookie "запам'ятати мене":

if (Auth::viaRemember()) {
    //
}

Інші методи автентифікації

Аутентифікуйте екземпляр користувача

Якщо вам потрібно зареєструвати існуючий екземпляр користувача у своїй програмі, ви можете зателефонувати доloginметод з екземпляром користувача. Даний об'єкт повинен бути реалізацієюIlluminate\Contracts\Auth\Authenticatableконтракт.App\Models\Userмодель, що входить до складу Laravel, вже реалізує цей інтерфейс. Цей метод автентифікації корисний, коли у вас вже є дійсний екземпляр користувача, наприклад безпосередньо після того, як користувач зареєструється у вашій програмі:

Auth::login($user);

// Login and "remember" the given user...
Auth::login($user, true);

Ви можете вказати екземпляр охорони, який ви хотіли б використовувати:

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

Аутентифікуйте користувача за ідентифікатором

Для входу користувача до програми за його ідентифікатором ви можете використовуватиloginUsingIdметод. Цей метод приймає первинний ключ користувача, якого потрібно аутентифікувати:

Auth::loginUsingId(1);

// Login and "remember" the given user...
Auth::loginUsingId(1, true);

Один раз автентифікуйте користувача

Ви можете використовуватиonceметод входу користувача до програми для одного запиту. Жодні сеанси чи файли cookie використовувати не будуть, а це означає, що цей метод може бути корисним при створенні API без авторизації:

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

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

Базова автентифікація HTTPзабезпечує швидкий спосіб автентифікації користувачів вашої програми без налаштування спеціальної сторінки для входу. Для початку прикріпітьauth.basicMiddlewareдо вашого маршруту.auth.basicMiddleware входить до фреймворку Laravel, тому вам не потрібно його визначати:

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

Як тільки Middleware буде приєднано до маршруту, вам автоматично буде запропоновано ввести облікові дані під час доступу до маршруту у вашому браузері. За замовчуваннямauth.basicMiddleware буде використовуватиemailстовпець на записі користувача як "ім'я користувача".

Примітка щодо FastCGI

Якщо ви використовуєте PHP FastCGI, автентифікація HTTP Basic може не працювати належним чином. Наступні рядки слід додати до вашого.htaccessфайл:

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

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

Ви також можете використовувати базову автентифікацію HTTP, не встановлюючи в сеансі файл cookie ідентифікатора користувача, що особливо корисно для автентифікації API. Робити так,визначити Middlewareщо викликає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 enter...
})->middleware('auth.basic.once');

Вихід

Щоб вручну вийти з програми, ви можете використовуватиlogoutметод наAuthфасад. Це очистить інформацію про автентифікацію в сеансі користувача:

use Illuminate\Support\Facades\Auth;

Auth::logout();

Недійсні сеанси на інших пристроях

Laravel також надає механізм анулювання та "виходу з системи" сеансів користувача, які активні на інших пристроях, без анулювання сеансу на їх поточному пристрої. Ця функція зазвичай використовується, коли користувач змінює або оновлює свій пароль, і ви хочете скасувати сеанси на інших пристроях, зберігаючи при цьому справжній пристрій автентифікованим.

Перед початком роботи слід переконатися, щоIlluminate\Session\Middleware\AuthenticateSessionMiddleware присутнє і не коментується у вашомуapp/Http/Kernel.phpклас 'webгрупа проміжного програмного забезпечення:

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

Потім ви можете використовуватиlogoutOtherDevicesметод наAuthфасад. Цей метод вимагає від користувача надати свій поточний пароль, який ваша програма повинна прийняти через форму введення:

use Illuminate\Support\Facades\Auth;

Auth::logoutOtherDevices($password);

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

При використанніAuthenticateSessionMiddleware в поєднанні з назвою власного маршруту дляloginмаршруту, ви повинні замінитиunauthenticatedна обробнику винятків вашої програми, щоб правильно перенаправити користувачів на вашу сторінку входу.

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

Створюючи додаток, іноді у вас можуть бути дії, які вимагають від користувача підтвердження свого пароля перед виконанням дії. Laravel включає вбудоване Middleware, щоб зробити цей процес легким. Реалізація цієї функції вимагатиме від вас визначення двох маршрутів: одного маршруту для відображення View з проханням користувача підтвердити свій пароль та одного маршруту для підтвердження дійсності пароля та перенаправлення користувача до передбачуваного пункту призначення.

У наступній документації обговорюється, як безпосередньо інтегрувати функції підтвердження пароля Laravel; однак, якщо ви хочете розпочати роботу швидше,Laravel JetstreamПакет аутентифікаційних лісів включає підтримку цієї функції!

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

Після підтвердження свого пароля користувач не попросить підтвердити свій пароль ще протягом трьох годин. Однак ви можете налаштувати тривалість часу до того, як користувач отримає повторний запит на введення пароля, змінивши значенняpassword_timeoutзначення конфігурації у вашомуauthфайл конфігурації.

Routing

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

Спочатку ми визначимо маршрут, необхідний для відображення View з проханням підтвердити свій пароль від користувача:

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

Як і слід було очікувати, View, яке повертається цим маршрутом, повинно мати форму, що міститьpasswordполе. Крім того, не соромтеся включати до View текст, який пояснює, що користувач входить до захищеної зони програми та повинен підтвердити свій пароль.

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

Далі ми визначимо маршрут, який буде обробляти запит на форму з View "підтвердити пароль". Цей маршрут нестиме відповідальність за перевірку пароля та перенаправлення користувача за призначенням:

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

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'])->name('password.confirm');

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

Захист маршрутів

Ви повинні переконатися, що будь-якому маршруту, який виконує дію, яка вимагає нещодавнього підтвердження пароля, присвоєноpassword.confirmMiddleware. Це Middleware входить до інсталяції Laravel за замовчуванням і автоматично зберігає призначене для користувача призначення в сеансі, щоб користувач міг бути перенаправлений у це місце після підтвердження свого пароля. Після збереження призначеного для користувача призначення у сеансі, Middleware перенаправить користувача наpassword.confirmназваний маршрут:

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

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

Додавання спеціальних гвардій

Ви можете визначити власні охоронці автентифікації, використовуючиextendметод наAuthфасад. Вам слід зробити цей дзвінокextendв межах aпостачальник послуг. Оскільки 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 method should return an implementation of 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) {
        return User::where('token', $request->token)->first();
    });
}

Після того, як визначено ваш власний драйвер автентифікації, ви використовуєте його як драйвер уguardsконфігурація вашогоauth.phpфайл конфігурації:

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

Додавання користувацьких постачальників послуг

Якщо ви не використовуєте традиційну реляційну базу даних для зберігання своїх користувачів, вам доведеться розширити Laravel за допомогою власного постачальника користувачів аутентифікації. Ми будемо використовуватиproviderметод наAuthFacadeдля визначення користувацького постачальника послуг:

<?php

namespace App\Providers;

use App\Extensions\RiakUserProvider;
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('riak', function ($app, array $config) {
            // Return an instance of Illuminate\Contracts\Auth\UserProvider...

            return new RiakUserProvider($app->make('riak.connection'));
        });
    }
}

Після реєстрації постачальника за допомогоюproviderВи можете переключитися на нового постачальника користувачів у своємуauth.phpфайл конфігурації. Спочатку визначте aproviderякий використовує ваш новий драйвер:

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

Нарешті, ви можете використовувати цього постачальника у своємуguardsконфігурація:

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

Договір про надання послуг користувачем

Illuminate\Contracts\Auth\UserProviderреалізації відповідають лише за отриманняIlluminate\Contracts\Auth\Authenticatableреалізація із стійкої системи зберігання, такої як MySQL, Riak тощо. Ці два інтерфейси дозволяють механізмам автентифікації 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метод оновлює$userполеremember_tokenз новим$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 включає aUserкласу вapp/Modelsкаталог, який реалізує цей інтерфейс, тому ви можете проконсультуватися з цим класом для прикладу реалізації.

Події

Laravel виховує різноманітніподіїпід час процесу автентифікації. Ви можете приєднати Listeners до цих подій у своєму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',
    ],
];