Skip to main content

Introduction

Password reset is an essential authentication flow for web applications. If you use a starter kit, this feature is built for you automatically, but for API-only projects and projects with a custom UI, you’ll need to implement it manually. When manual implementation is required:
  • API-only backends (frontend is an SPA or mobile app)
  • Building your own authentication UI without using a starter kit
  • When you want to fully customize the mail notification and reset URL design
If you created your project using a starter kit (laravel new), password reset is already implemented. This page describes how to implement it without a starter kit.
The full password reset flow looks like this:

Configuration

Password reset configuration is managed under the passwords key in config/auth.php.
  • driver — how data is stored (database or cache)
  • expire — token expiration (in minutes). Default is 60 minutes
  • throttle — wait time (in seconds) before another send is allowed

Drivers

The database driver

The default driver. It stores password reset tokens in the database password_reset_tokens table. This table is included in Laravel’s default migration (0001_01_01_000000_create_users_table.php).

The cache driver

A newer option available since Laravel 11. Since it doesn’t require a database table, you can implement password reset in a simpler setup.
The cache driver stores tokens in the cache store. It removes the need for the password_reset_tokens migration. Tokens are stored keyed by the user’s email address, so avoid using the email address as a cache key elsewhere in your app.
Specifying a dedicated cache store under the store key prevents reset data from being erased by php artisan cache:clear. The value should match a store name configured in config/cache.php.

Preparing your model

To use password reset, the App\Models\User model needs two traits.
  • Notifiable — required to send mail notifications
  • CanResetPassword — provides methods needed for generating and verifying password reset tokens
Laravel’s default User model already includes these traits. On a fresh install you don’t need to add them.

Implementing routes

Password reset requires four routes. Displays a form for the user to enter their email address.
The corresponding Blade view:
Receives the form submission and uses Password::sendResetLink() to send the reset email.
Password::sendResetLink() returns a status string.

3. The password reset form

Displays a form for the user to enter a new password after clicking the link in the email.
The corresponding Blade view:

4. Executing the password reset

Receives the form and updates the password with Password::reset().
Status constants for Password::reset():

Token expiration

You can set the token expiration in minutes via the expire option in config/auth.php. The default is 60 minutes.
When using the database driver, expired tokens remain in the database. To clean them up periodically, use the following Artisan command.
We recommend automating this via the scheduler.

Customization

Using a custom notification

To customize the password reset email, override the sendPasswordResetNotification method on your User model.
Use ResetPassword::createUrlUsing() in your AppServiceProvider’s boot method to change the reset link URL. This is useful when redirecting to a frontend on a different origin, such as an SPA.

Configuring Trusted Hosts

Password reset links are generated using the Host header of the HTTP request. To prevent requests from unauthorized hosts, we recommend configuring Trusted Hosts in bootstrap/app.php.
When implementing password reset, always review your Trusted Hosts configuration. Insufficient configuration risks host header injection attacks.

Summary

Next steps

Authentication introduction

Learn the overall architecture of Laravel’s authentication system.

Notifications

Learn about customizing mail notifications in detail.
Last modified on July 13, 2026