Скидання паролів
Вступ
Більшість веб-застосунків надають спосіб для користувачів скинути забуті паролі. Замість того, щоб змушувати вас повторно реалізовувати це вручну для кожного застосунку, який ви створюєте, Laravel надає зручні сервіси для відправки посилань на скидання пароля та безпечного скидання паролів.
Хочете швидко почати? Встановіть стартовий комплект застосунку у новому застосунку Laravel. Стартові комплекти Laravel подбають про створення всієї вашої системи аутентифікації, включаючи скидання забутих паролів.
Конфігурація
Файл конфігурації скидання пароля вашого застосунку зберігається у config/auth.php. Обов'язково перегляньте доступні вам параметри в цьому файлі. За замовчуванням Laravel налаштований на використання драйвера скидання пароля database.
Опція конфігурації driver скидання пароля визначає, де будуть зберігатися дані для скидання пароля. Laravel включає два драйвери:
database- дані для скидання пароля зберігаються в реляційній базі даних.cache- дані скидання пароля зберігаються в одному з ваших сховищ на основі кешу.
Вимоги до драйвера
База даних
Коли використовується драйвер за замовчуванням database, необхідно створити таблицю для зберігання токенів скидання паролів вашого застосунку. Зазвичай, це включено в стандартну міграцію бази даних Laravel 0001_01_01_000000_create_users_table.php.
Кеш
Також доступний драйвер кешу для обробки скидання паролів, який не потребує окремої таблиці бази даних. Записи індексуються за адресою електронної пошти користувача, тому переконайтеся, що ви не використовуєте адреси електронної пошти як ключ кешу в іншому місці вашого застосунку:
'passwords' => [ 'users' => [ 'driver' => 'cache', 'provider' => 'users', 'store' => 'passwords', // Опціонально... 'expire' => 60, 'throttle' => 60, ], ],
Щоб запобігти очищенню даних скидання пароля під час виклику artisan cache:clear, ви можете за бажанням вказати окреме сховище кешу за допомогою конфігураційного ключа store. Значення повинно відповідати сховищу, налаштованому у вашому конфігураційному файлі config/cache.php.
Підготовка моделі
Перш ніж використовувати функції скидання пароля в Laravel, модель App\Models\User вашого застосунку повинна використовувати трейд Illuminate\Notifications\Notifiable. Зазвичай цей трейд вже включено в модель App\Models\User за замовчуванням, яка створюється з новими застосунками Laravel.
Далі, переконайтеся, що ваша модель App\Models\User реалізує контракт Illuminate\Contracts\Auth\CanResetPassword. Модель App\Models\User, що входить до складу фреймворку, вже реалізує цей інтерфейс і використовує трейт Illuminate\Auth\Passwords\CanResetPassword для включення методів, необхідних для реалізації інтерфейсу.
Налаштування Довірених Хостів
За замовчуванням Laravel буде відповідати на всі запити, які він отримує, незалежно від вмісту заголовка Host HTTP-запиту. Крім того, значення заголовка Host буде використовуватися при генерації абсолютних URL-адрес до вашого застосунку під час веб-запиту.
Зазвичай, ви повинні налаштувати ваш веб-сервер, такий як Nginx або Apache, щоб він надсилав запити до вашого застосунку лише з певним ім'ям хоста. Однак, якщо у вас немає можливості безпосередньо налаштувати ваш веб-сервер і вам потрібно вказати Laravel відповідати лише на певні імена хостів, ви можете зробити це, використовуючи метод trustHosts middleware у файлі bootstrap/app.php вашого застосунку. Це особливо важливо, коли ваш застосунок пропонує функціональність скидання пароля.
Щоб дізнатися більше про цей метод middleware, будь ласка, зверніться до документації TrustHosts middleware.
Маршрутизація
Щоб належним чином реалізувати підтримку для дозволу користувачам скидати свої паролі, нам потрібно визначити кілька маршрутів. По-перше, нам потрібна пара маршрутів для обробки запиту користувача на отримання посилання для скидання пароля через їхню електронну адресу. По-друге, нам потрібна пара маршрутів для обробки фактичного скидання пароля, коли користувач відвідує посилання для скидання пароля, яке було надіслано їм електронною поштою, і заповнює форму скидання пароля.
Запит посилання для скидання пароля
Форма запиту на скидання пароля
Спочатку ми визначимо маршрути, які потрібні для запиту посилань на скидання пароля. Для початку ми визначимо маршрут, який повертає представлення з формою запиту посилання на скидання пароля:
Route::get('/forgot-password', function () {
return view('auth.forgot-password');
})->middleware('guest')->name('password.request');
Представлення, яке повертається цим маршрутом, повинно містити форму з полем email, яке дозволить користувачу запросити посилання для скидання пароля для вказаної електронної адреси.
Обробка відправлення форми
Далі ми визначимо маршрут, який обробляє запит на відправку форми з представлення "забули пароль". Цей маршрут буде відповідальним за перевірку адреси електронної пошти та відправку запиту на скидання пароля відповідному користувачу:
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;
Route::post('/forgot-password', function (Request $request) {
$request->validate(['email' => 'required|email']);
$status = Password::sendResetLink(
$request->only('email')
);
return $status === Password::ResetLinkSent
? back()->with(['status' => __($status)])
: back()->withErrors(['email' => __($status)]);
})->middleware('guest')->name('password.email');
Перш ніж продовжити, давайте детальніше розглянемо цей маршрут. Спочатку атрибут email запиту перевіряється. Далі ми скористаємося вбудованим у Laravel "password broker" (через фасад Password), щоб надіслати користувачу посилання для скидання пароля. Password broker подбає про отримання користувача за вказаним полем (у цьому випадку, адресою електронної пошти) і надішле користувачу посилання для скидання пароля через вбудовану в Laravel систему сповіщень.
Метод sendResetLink повертає "status" слаг. Цей статус може бути перекладений за допомогою локалізаційних хелперів Laravel, щоб відобразити користувачу зручне повідомлення про статус їх запиту. Переклад статусу скидання пароля визначається мовним файлом вашого застосунку lang/{lang}/passwords.php. Запис для кожного можливого значення статусу слага знаходиться у мовному файлі passwords.
За замовчуванням, скелет застосунку Laravel не включає директорію lang. Якщо ви хочете налаштувати мовні файли Laravel, ви можете опублікувати їх за допомогою команди Artisan lang:publish.
Ви можете запитати, як Laravel знає, як отримати запис користувача з бази даних вашого застосунку при виклику методу sendResetLink фасаду Password. Брокер паролів Laravel використовує "постачальників користувачів" вашої системи автентифікації для отримання записів з бази даних. Постачальник користувачів, який використовується брокером паролів, налаштовується в масиві конфігурації passwords у вашому конфігураційному файлі config/auth.php. Щоб дізнатися більше про написання власних постачальників користувачів, зверніться до документації з автентифікації.
Коли ви вручну реалізуєте скидання пароля, вам потрібно самостійно визначити вміст представлень і маршрутів. Якщо ви хочете використовувати шаблон, що включає всю необхідну логіку аутентифікації та верифікації, перегляньте стартові набори Laravel застосунків.
Скидання пароля
Форма скидання пароля
Далі ми визначимо маршрути, необхідні для фактичного скидання пароля, коли користувач натискає на посилання для скидання пароля, яке було надіслано їм електронною поштою, і надає новий пароль. Спочатку давайте визначимо маршрут, який відобразить форму скидання пароля, що відображається, коли користувач натискає на посилання для скидання пароля. Цей маршрут отримає параметр token, який ми використаємо пізніше для перевірки запиту на скидання пароля:
Route::get('/reset-password/{token}', function (string $token) {
return view('auth.reset-password', ['token' => $token]);
})->middleware('guest')->name('password.reset');
Представлення, яке повертається цим маршрутом, повинно відображати форму, що містить поле email, поле password, поле password_confirmation та приховане поле token, яке повинно містити значення секретного $token, отриманого нашим маршрутом.
Обробка відправлення форми
Звичайно, нам потрібно визначити маршрут для обробки відправки форми скидання пароля. Цей маршрут буде відповідальним за валідацію вхідного запиту та оновлення пароля користувача в базі даних:
use App\Models\User;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Str;
Route::post('/reset-password', function (Request $request) {
$request->validate([
'token' => 'required',
'email' => 'required|email',
'password' => 'required|min:8|confirmed',
]);
$status = Password::reset(
$request->only('email', 'password', 'password_confirmation', 'token'),
function (User $user, string $password) {
$user->forceFill([
'password' => Hash::make($password)
])->setRememberToken(Str::random(60));
$user->save();
event(new PasswordReset($user));
}
);
return $status === Password::PasswordReset
? redirect()->route('login')->with('status', __($status))
: back()->withErrors(['email' => [__($status)]]);
})->middleware('guest')->name('password.update');
Перш ніж продовжити, давайте детальніше розглянемо цей маршрут. Спочатку атрибути запиту token, email та password перевіряються. Далі ми використаємо вбудований "password broker" Laravel (через фасад Password) для перевірки облікових даних запиту на скидання пароля.
Якщо токен, адреса електронної пошти та пароль, надані брокеру паролів, є дійсними, буде викликано замикання, передане методу reset. У цьому замиканні, яке отримує екземпляр користувача та пароль у відкритому тексті, наданий у формі скидання пароля, ми можемо оновити пароль користувача в базі даних.
Метод reset повертає "статус" слаг. Цей статус може бути перекладений за допомогою локалізаційних хелперів Laravel, щоб відобразити користувачеві зручне повідомлення про статус їх запиту. Переклад статусу скидання пароля визначається мовним файлом вашого застосунку lang/{lang}/passwords.php. Запис для кожного можливого значення статусу слаг знаходиться в мовному файлі passwords. Якщо ваш застосунок не містить директорії lang, ви можете створити її за допомогою команди Artisan lang:publish.
Перш ніж продовжити, ви можете запитати, як Laravel знає, як отримати запис користувача з бази даних вашого застосунку при виклику методу reset фасаду Password. Менеджер паролів Laravel використовує "постачальників користувачів" вашої системи автентифікації для отримання записів з бази даних. Постачальник користувачів, який використовується менеджером паролів, налаштовується в масиві конфігурації passwords у вашому конфігураційному файлі config/auth.php. Щоб дізнатися більше про написання власних постачальників користувачів, зверніться до документації з автентифікації.
Видалення прострочених токенів
Якщо ви використовуєте драйвер database, токени скидання пароля, термін дії яких закінчився, все ще будуть присутні у вашій базі даних. Однак ви можете легко видалити ці записи, використовуючи Artisan команду auth:clear-resets:
php artisan auth:clear-resets
Якщо ви хочете автоматизувати цей процес, розгляньте можливість додавання команди до планувальника вашого застосунку:
use Illuminate\Support\Facades\Schedule;
Schedule::command('auth:clear-resets')->everyFifteenMinutes();
Налаштування
Налаштування посилання для скидання
Ви можете налаштувати URL-адресу посилання для скидання пароля, використовуючи метод createUrlUsing, наданий класом сповіщення ResetPassword. Цей метод приймає замикання, яке отримує екземпляр користувача, що отримує сповіщення, а також токен посилання для скидання пароля. Зазвичай, ви повинні викликати цей метод з методу boot вашого сервіс-провайдера App\Providers\AppServiceProvider:
use App\Models\User; use Illuminate\Auth\Notifications\ResetPassword; /** * Ініціалізувати будь-які служби застосунку. */ public function boot(): void { ResetPassword::createUrlUsing(function (User $user, string $token) { return 'https://example.com/reset-password?token='.$token; }); }
Налаштування Скидання Електронної Пошти
Ви можете легко змінити клас сповіщення, який використовується для відправки посилання на скидання пароля користувачу. Щоб почати, перевизначте метод sendPasswordResetNotification у вашій моделі App\Models\User. У цьому методі ви можете відправити сповіщення, використовуючи будь-який клас сповіщень власного створення. Токен скидання пароля $token є першим аргументом, отриманим методом. Ви можете використовувати цей $token для створення URL скидання пароля на ваш вибір і відправки вашого сповіщення користувачу:
use App\Notifications\ResetPasswordNotification; /** * Надіслати користувачу сповіщення про скидання пароля. * * @param string $token */ public function sendPasswordResetNotification($token): void { $url = 'https://example.com/reset-password?token='.$token; $this->notify(new ResetPasswordNotification($url)); }
