Password Reset Functionality in Laravel 12

As a Laravel enthusiast, I’m excited to share how to implement password reset functionality in Laravel 12. This feature is a must-have for any web app, ensuring users can securely recover their accounts. Laravel 12, with its robust authentication system, makes this process seamless.

In this guide, I’ll walk you through each step, from setup to customization, using simple language and practical examples.

Step-by-Step Guide to Implement Password Reset in Laravel 12

Password Reset Functionality in Laravel 12

Implementing a password reset feature in Laravel 12 is straightforward, thanks to its built-in authentication tools like Laravel Breeze or Fortify. Below, I’ll guide you through the process with clear steps and code snippets to ensure a secure and user-friendly experience.

Step 1: Set Up a Laravel 12 Project

First, ensure you have a Laravel 12 installed. Open your terminal and create a new project:

composer create-project --prefer-dist laravel/laravel password-reset-app
cd password-reset-app

Run the development server:

php artisan serve

This sets up a fresh Laravel 12 application. Ensure you have a database (MySQL, PostgreSQL, or SQLite) configured in the .env file.

 

Step 2: Install Laravel Breeze for Authentication

Laravel Breeze provides a quick way to scaffold authentication, including password reset. Install it using:

composer require laravel/breeze --dev
php artisan breeze:install

Choose the Blade stack for simplicity, and run:

npm install && npm run dev
php artisan migrate

This command sets up the authentication system, including login, registration, and password reset views.

 

Step 3: Configure the User Model

Ensure your App\Models\User model uses the Notifiable trait and implements the CanResetPassword contract. Laravel 12’s default User model already includes these:

namespace App\Models;

use Illuminate\Contracts\Auth\CanResetPassword;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable implements CanResetPassword
{
    use Notifiable;
    // Other model properties and methods
}

This enables sending password reset notifications.

 

Step 4: Set Up the Password Reset Table

Laravel requires a password_resets table to store reset tokens. The migration is included by default. Run:

php artisan migrate

This creates the password_resets table with email, token, and created_at columns.

 

Step 5: Configure Email Settings

Password reset links are sent via email, so configure your mail settings in the env file. For testing, use a service like Mailtrap:

MAIL_MAILER=smtp
MAIL_HOST=sandbox.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=your_username
MAIL_PASSWORD=your_password
[email protected]
MAIL_FROM_NAME="${APP_NAME}"

Test email configuration to ensure emails are sent correctly.

 

Step 6: Define Password Reset Routes

Laravel Breeze sets up the necessary routes in routes/auth.php. Verify the following routes exist:

use App\Http\Controllers\Auth\ForgotPasswordController;
use App\Http\Controllers\Auth\ResetPasswordController;

Route::get('password/reset', [ForgotPasswordController::class, 'showLinkRequestForm'])->name('password.request');
Route::post('password/email', [ForgotPasswordController::class, 'sendResetLinkEmail'])->name('password.email');
Route::get('password/reset/{token}', [ResetPasswordController::class, 'showResetForm'])->name('password.reset');
Route::post('password/reset', [ResetPasswordController::class, 'reset'])->name('password.update');

These routes handle the password reset request form, email sending, reset form display, and password update.

 

Step 7: Customize the Password Reset Email

Customize the email template by overriding the sendPasswordResetNotification method in the User model:

use App\Notifications\CustomResetPassword;

public function sendPasswordResetNotification($token)
{
    $this->notify(new CustomResetPassword($token));
}

Create a notification class:

php artisan make:notification CustomResetPassword

Edit app/Notifications/CustomResetPassword.php:

namespace App\Notifications;

use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class CustomResetPassword extends Notification
{
    public $token;

    public function __construct($token)
    {
        $this->token = $token;
    }

    public function via($notifiable)
    {
        return ['mail'];
    }

    public function toMail($notifiable)
    {
        return (new MailMessage)
            ->subject('Reset Your Password')
            ->line('Click the button below to reset your password.')
            ->action('Reset Password', url('/password/reset/'.$this->token))
            ->line('If you didn’t request this, ignore this email.');
    }
}

This creates a branded email with a clickable reset link.

 

Step 8: Customize Views

Edit the Blade templates in resources/views/auth/ to match your app’s design. For example, modify password-email.blade.php:

<!DOCTYPE html>
<html>
<head>
    <title>Reset Password</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container mt-5">
        <h2>Reset Password</h2>
        @if (session('status'))
            <div class="alert alert-success">
                {{ session('status') }}
            </div>
        @endif
        <form method="POST" action="{{ route('password.email') }}">
            @csrf
            <div class="mb-3">
                <label for="email" class="form-label">Email Address</label>
                <input type="email" name="email" class="form-control @error('email') is-invalid @enderror" required>
                @error('email')
                    <div class="invalid-feedback">{{ $message }}</div>
                @enderror
            </div>
            <button type="submit" class="btn btn-primary">Send Password Reset Link</button>
        </form>
    </div>
</body>
</html>

Similarly, update reset-password.blade.php for the reset form.

 

Step 9: Test the Password Reset Flow
  1. Visit /password/reset and enter a registered email.
  2. Check the email for the reset link (use Mailtrap for testing).
  3. Click the link to access the reset form.
  4. Enter a new password and submit.
  5. Verify you can log in with the new password.

 

Step 10: Add Security Enhancements
  • Rate Limiting: Prevent abuse by adding rate limiting to the reset endpoint in app/Providers/RouteServiceProvider.php:
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;

protected function configureRateLimiting()
{
    RateLimiter::for('password-reset', function () {
        return Limit::perMinute(5)->by(request()->ip());
    });
}
  • Clear Expired Tokens: Schedule the auth:clear-resets command to remove expired tokens:
use Illuminate\Support\Facades\Schedule;

Schedule::command('auth:clear-resets')->everyFifteenMinutes();

 

Step 11: Add Logging

Log password reset attempts for security auditing. Create a middleware:

php artisan make:middleware LogPasswordReset

Edit app/Http/Middleware/LogPasswordReset.php:

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Log;

class LogPasswordReset
{
    public function handle($request, Closure $next)
    {
        Log::info('Password reset attempt', [
            'email' => $request->email,
            'ip' => $request->ip(),
        ]);
        return $next($request);
    }
}

Register it in app/Http/Kernel.php and apply it to the reset routes.

 

Conclusion

Implementing password reset functionality in Laravel 12 is both powerful and user-friendly, thanks to its built-in authentication tools. By following this guide, you’ve created a secure, customizable password reset flow that enhances user experience and app security.

Laravel’s flexibility allows you to tailor the feature to your needs, from custom emails to advanced security measures. Keep exploring Laravel 12’s documentation for more ways to optimize authentication and make your app stand out.

 

Frequently Asked Questions (FAQs)

  1. Do I need Laravel Breeze to implement password reset in Laravel 12?

    No, you can manually set up password reset using Laravel Fortify or custom routes and controllers. Breeze just simplifies it with built-in scaffolding.

  2. How can I test emails without sending real ones?

    Use a service like Mailtrap to capture and preview emails in a test environment. Just configure it in your env file.

  3. What happens if a user doesn’t receive the reset email?

    Check your mail driver settings, inspect spam folders, and ensure the correct email address was entered. Also, log email dispatch attempts for debugging.

  4. Can I customize the password reset URL?

    Yes. You can use ResetPassword::createUrlUsing in AppServiceProvider to define custom password reset link behavior and structure.

  5. How do I secure the password reset process?

    Use rate limiting, input validation, logging, and automatic token expiration to prevent misuse and ensure a secure password reset flow.

 


You might also like:

techsolutionstuff

Techsolutionstuff | The Complete Guide

I'm a software engineer and the founder of techsolutionstuff.com. Hailing from India, I craft articles, tutorials, tricks, and tips to aid developers. Explore Laravel, PHP, MySQL, jQuery, Bootstrap, Node.js, Vue.js, and AngularJS in our tech stack.

RECOMMENDED POSTS

FEATURE POSTS