Step 1: Set Up Email Configuration

Laravel needs a mail driver configured to send emails.

  1. Open .env file and configure your mail settings. For example, using Gmail SMTP:

MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=your_email@gmail.com
MAIL_PASSWORD=your_app_password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=your_email@gmail.com
MAIL_FROM_NAME="${APP_NAME}"
  • Note: For Gmail, you need to generate an App Password if 2FA is enabled.
  1. Clear config cache:

php artisan config:cache

Step 2: Use Laravel’s Built-in Auth Scaffolding

Laravel comes with a built-in system for password reset. If you don’t already have authentication scaffolding, you can install Laravel Breeze (or Jetstream/Ui):

composer require laravel/breeze --dev
php artisan breeze:install
npm install && npm run dev
php artisan migrate

This will generate login, register, forgot password, and reset password views and routes.

Step 3: Routes

Laravel automatically registers the routes for password reset when you use Breeze/Jetstream. You can check routes using:

php artisan route:list

Key routes:

Method URI Action
GET /forgot-password showForgotPasswordForm
POST /forgot-password sendResetLinkEmail
GET /reset-password/{token} showResetPasswordForm
POST /reset-password reset

Step 4: Forgot Password Form

The default form is located in resources/views/auth/forgot-password.blade.php:

<form method="POST" action="{{ route('password.email') }}">
@csrf
<label for="email">Email Address</label>
<input id="email" type="email" name="email" required autofocus>

<button type="submit">
Send Password Reset Link
</button>
</form>

When submitted, it hits the sendResetLinkEmail controller.

Step 5: Send Reset Link

Laravel handles this in the controller using Password::sendResetLink.

Example controller (ForgotPasswordController.php):

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;
public function sendResetLinkEmail(Request $request) { $request->validate([ 'email' => 'required|email|exists:users,email', ]); $status = Password::sendResetLink( $request->only('email') ); return $status === Password::RESET_LINK_SENT ? back()->with(['status' => __($status)]) : back()->withErrors(['email' => __($status)]); }
  • Laravel automatically sends a reset link email using notifications.

Step 6: Reset Password Form

When a user clicks the email link, they go to /reset-password/{token}.

Default view: resources/views/auth/reset-password.blade.php

<form method="POST" action="{{ route('password.update') }}">
@csrf
<input type="hidden" name="token" value="{{ $request->route('token') }}"><label>Email</label>
<input type="email" name="email" value="{{ old('email', $request->email) }}" required>

<label>Password</label>
<input type="password" name="password" required>

<label>Confirm Password</label>
<input type="password" name="password_confirmation" required>

<button type="submit">Reset Password</button>
</form>

Step 7: Handle Password Reset

Laravel handles password reset in ResetPasswordController:

use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;>public function reset(Request $request)
{
$request->validate([
'token' => 'required',
'email' => 'required|email|exists:users,email',
'password' => 'required|confirmed|min:8',
]);

$status = Password::reset(
$request->only('email', 'password', 'password_confirmation', 'token'),
function ($user, $password) {
$user->forceFill([
'password' => Hash::make($password)
])->save();
}
);

return $status === Password::PASSWORD_RESET
? redirect()->route('login')->with('status', __($status))
: back()->withErrors(['email' => [__($status)]]);
}

Step 8: Customize Email

The default email is sent using Illuminate\Auth\Notifications\ResetPassword. To customize:

php artisan make:notification ResetPasswordNotification

Edit toMail() in ResetPasswordNotification.php:

public function toMail($notifiable)
{
return (new MailMessage)
->subject('Reset Your Password')
->line('Click the button below to reset your password.')
->action('Reset Password', url(route('password.reset', $this->token, false)))
->line('If you did not request a password reset, no further action is required.');
}

Then override sendPasswordResetNotification in the User model:

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

Categorized in:

Laravel,