Реализация восстановления пароля на сайте
Восстановление пароля — стандартный флоу Forgot Password. Пользователь вводит email, получает письмо со ссылкой для сброса, задаёт новый пароль. Реализуется через токен с коротким TTL, хранящийся в виде хэша в БД.
Флоу
- POST /forgot-password — создать токен, отправить письмо
- GET /reset-password?token=...&email=... — форма нового пароля
- POST /reset-password — верифицировать токен, сменить пароль, удалить токен
Laravel Password Broker
Laravel включает встроенный механизм восстановления:
Хранение токенов
Laravel хранит bcrypt-хэш токена в таблице :
| token (bcrypt) | created_at | |
|---|---|---|
| [email protected] | y0$... | 2024-01-15 10:00 |
Токен действует 60 минут (параметр в -> ). Устаревшие записи удаляются командой [41;1m Illuminate\Database\QueryException [49;22m
[39;1m SQLSTATE[08006] [7] could not connect to server: Connection refused (0x0000274D/10061) Is the server running on host "127.0.0.1" and accepting TCP/IP connections on port 5433? (SQL: delete from "password_resets" where "created_at" < 2026-03-28 15:13:44)[39;22m
at [32mD:\domains\atlas.loc\vendor\laravel\framework\src\Illuminate\Database\Connection.php[39m:[32m760[39m 756▕ // If an exception occurs when attempting to run a query, we'll format the error 757▕ // message to include the bindings with SQL, which will make this exception a 758▕ // lot more helpful to the developer instead of just the database's errors. 759▕ catch (Exception $e) { ➜ 760▕ throw new QueryException( 761▕ $query, $this->prepareBindings($bindings), $e 762▕ ); 763▕ } 764▕ }
[33m1 [39m[39;1mD:\domains\atlas.loc\vendor\laravel\framework\src\Illuminate\Database\Connectors\Connector.php[39;22m:[39;1m70[39;22m [90m PDOException::("SQLSTATE[08006] [7] could not connect to server: Connection refused (0x0000274D/10061) Is the server running on host "127.0.0.1" and accepting TCP/IP connections on port 5433?")[39m
[33m2 [39m[39;1mD:\domains\atlas.loc\vendor\laravel\framework\src\Illuminate\Database\Connectors\Connector.php[39;22m:[39;1m70[39;22m [90m PDO::__construct("pgsql:host=127.0.0.1;dbname='truetech';port=5433;sslmode=prefer", "truetech", Object(SensitiveParameterValue), [])[39m — рекомендуется добавить в cron.
Безопасность
- Одинаковый ответ для существующих и несуществующих email — не раскрывать наличие аккаунта
- Rate limiting: не более 3 запросов в час с одного email или IP
- После использования токен удаляется немедленно
- При смене пароля инвалидировать все активные сессии пользователя
Кастомный шаблон письма
Ссылка в письме строится как:
Сроки
1–2 рабочих дня включая кастомный шаблон письма и rate limiting.







