Password reset is an essential authentication flow for any web application. If you use a starter kit, this feature is scaffolded automatically. For API-only projects, SPAs, or applications with a custom UI, you need to implement it manually.When manual implementation is required:
API-only backends (frontend is a SPA or mobile app)
Building authentication UI without a starter kit
Fully customizing the email notification or reset URL
If you created your project with a starter kit (laravel new), password reset is already implemented. This page explains how to implement it without a starter kit.
The default driver. Password reset tokens are stored in the password_reset_tokens database table. This table is created by Laravel’s default migration (0001_01_01_000000_create_users_table.php).
Available since Laravel 11. The cache driver requires no database table, keeping your setup simpler.
The cache driver stores tokens in a cache store, eliminating the need for the password_reset_tokens table. Tokens are keyed by the user’s email address, so make sure you are not using email addresses as cache keys elsewhere in your application.
Specifying a dedicated store prevents php artisan cache:clear from wiping your reset tokens. The value must match a store name defined in config/cache.php.
Your App\Models\User model requires two traits for password reset to work:
<?phpnamespace App\Models;use Illuminate\Auth\Passwords\CanResetPassword;use Illuminate\Foundation\Auth\User as Authenticatable;use Illuminate\Notifications\Notifiable;class User extends Authenticatable{ use Notifiable, CanResetPassword; // ...}
Notifiable — required to send email notifications
CanResetPassword — provides methods for generating and validating password reset tokens
Laravel’s default User model already includes both traits. No changes are required for a fresh installation.
To customize the password reset email, override sendPasswordResetNotification on the User model.
use App\Notifications\ResetPasswordNotification;class User extends Authenticatable{ use Notifiable, CanResetPassword; /** * Send a password reset notification to the user. */ public function sendPasswordResetNotification($token): void { $url = 'https://example.com/reset-password?token='.$token; $this->notify(new ResetPasswordNotification($url)); }}
Use ResetPassword::createUrlUsing() in your AppServiceProvider to change the reset URL. This is useful when your frontend lives on a different origin, such as a SPA.
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; });}
Password reset links are generated using the Host header of the incoming HTTP request. Configure trusted hosts in bootstrap/app.php to prevent host header injection attacks.
Always configure trusted hosts when implementing password reset. Without it, attackers could manipulate the Host header to redirect reset links to a malicious domain.