In this tutorial, I will show you Laravel 11 Custom Forgot Password Tutorial application.
Laravel provides its own forget password functionality but if you want to create your custom forget password functionality then I will help to building a custom reset password function in php laravel. so basically, you can also create custom forget passwords with different models too. You Can Learn How to Customize Laravel Breeze Authentication
Step for Laravel 11 Custom Reset Password via Email Tutorial
- Step 1: Install Laravel 11
- Step 2: Create MySQL Table
- Step 3: Create Routes
- Step 4: Create Controller
- Step 5: Email Configuration
- Step 6: Create Blade Files
- Run Laravel App
Let start Laravel 11 Custom Forgot Password Tutorial
Step 1: Install Laravel 11
This step is not required; however, if you have not created the Laravel app, then you may go ahead and execute the below command:
composer create-project laravel/laravel example-app
Step 2: Create MySQL Table
basically, it will already created “password_resets” table migration but if it’s not created then you can create new migration as like bellow code:
database/migrations/2024_07_20_103428_create_password_resets_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePasswordResetsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up(): void
{
Schema::create('password_resets', function (Blueprint $table) {
$table->string('email')->index();
$table->string('token');
$table->timestamp('created_at')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down(): void
{
Schema::dropIfExists('password_resets');
}
}
Step 3: Create Routes
In this is step we need to create custom route for forget and reset link. so open your routes/web.php file and add following route.
routes/web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Auth\AuthController;
use App\Http\Controllers\Auth\ForgotPasswordController;
Route::get('/', function () {
return view('welcome');
});
Route::get('login', [AuthController::class, 'index'])->name('login');
Route::post('post-login', [AuthController::class, 'postLogin'])->name('login.post');
Route::get('registration', [AuthController::class, 'registration'])->name('register');
Route::post('post-registration', [AuthController::class, 'postRegistration'])->name('register.post');
Route::get('dashboard', [AuthController::class, 'dashboard']);
Route::post('logout', [AuthController::class, 'logout'])->name('logout');
// Routes for Forget Password
Route::get('forget-password', [ForgotPasswordController::class, 'showForgetPasswordForm'])->name('forget.password.get');
Route::post('forget-password', [ForgotPasswordController::class, 'submitForgetPasswordForm'])->name('forget.password.post');
Route::get('reset-password/{token}', [ForgotPasswordController::class, 'showResetPasswordForm'])->name('reset.password.get');
Route::post('reset-password', [ForgotPasswordController::class, 'submitResetPasswordForm'])->name('reset.password.post');
Step 4: Create Controller
in this step, we need to create ForgotPasswordController and add following code on that file:
app/Http/Controllers/Auth/ForgotPasswordController.php
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use DB;
use Carbon\Carbon;
use App\Models\User;
use Mail;
use Hash;
use Illuminate\Support\Str;
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;
class ForgotPasswordController extends Controller
{
/**
* Write code on Method
*
* @return response()
*/
public function showForgetPasswordForm(): View
{
return view('auth.forgetPassword');
}
/**
* Write code on Method
*
* @return response()
*/
public function submitForgetPasswordForm(Request $request): RedirectResponse
{
$request->validate([
'email' => 'required|email|exists:users',
]);
$token = Str::random(64);
DB::table('password_resets')->insert([
'email' => $request->email,
'token' => $token,
'created_at' => Carbon::now()
]);
Mail::send('emails.forgetPassword', ['token' => $token], function($message) use($request){
$message->to($request->email);
$message->subject('Reset Password');
});
return back()->with('message', 'We have e-mailed your password reset link!');
}
/**
* Write code on Method
*
* @return response()
*/
public function showResetPasswordForm($token): View
{
return view('auth.forgetPasswordLink', ['token' => $token]);
}
/**
* Write code on Method
*
* @return response()
*/
public function submitResetPasswordForm(Request $request): RedirectResponse
{
$request->validate([
'email' => 'required|email|exists:users',
'password' => 'required|string|min:6|confirmed',
'password_confirmation' => 'required'
]);
$updatePassword = DB::table('password_resets')
->where([
'email' => $request->email,
'token' => $request->token
])
->first();
if(!$updatePassword){
return back()->withInput()->with('error', 'Invalid token!');
}
$user = User::where('email', $request->email)
->update(['password' => Hash::make($request->password)]);
DB::table('password_resets')->where(['email'=> $request->email])->delete();
return redirect('/login')->with('message', 'Your password has been changed!');
}
}
Step 5: Email Configuration
in this step, we will add email configuration on env file, because we will send email to reset password link from controller:
.env
MAIL_DRIVER=smtp
MAIL_HOST=smtp-mail.outlook.com
MAIL_PORT=587
MAIL_USERNAME=example@hotmail.com
MAIL_PASSWORD=123456789
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=example@hotmail.com
Step 6: Create Blade Files
here, we need to create blade files for layout, login, register and home page. so let’s create one by one files:
resources/views/auth/forgetPassword.blade.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel 11 Custom Reset Password Functions</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<style type="text/css">
body{
background: #F8F9FA;
}
</style>
</head>
<body>
<section class="bg-light py-3 py-md-5">
<div class="container">
<div class="row justify-content-center">
<div class="col-12 col-sm-10 col-md-8 col-lg-6 col-xl-5 col-xxl-4">
<div class="card border border-light-subtle rounded-3 shadow-sm mt-5">
<div class="card-body p-3 p-md-4 p-xl-5">
<div class="text-center mb-3">
<a href="#!">
<img src="https://www.example.com/assets/images/logo.png" alt="BootstrapBrain Logo" width="250">
</a>
</div>
<h2 class="fs-6 fw-normal text-center text-secondary mb-4">Reset Password</h2>
<form method="POST" action="{{ route('forget.password.post') }}">
@csrf
@if (Session::has('message'))
<div class="alert alert-success" role="alert">
{{ Session::get('message') }}
</div>
@endif
@error('email')
<div class="alert alert-danger" role="alert">
<strong>{{ $message }}</strong>
</div>
@enderror
<div class="row gy-2 overflow-hidden">
<div class="col-12">
<div class="form-floating mb-3">
<input type="email" class="form-control @error('email') is-invalid @enderror" name="email" id="email" placeholder="name@example.com" required>
<label for="email" class="form-label">{{ __('Email Address') }}</label>
</div>
</div>
<div class="col-12">
<div class="d-grid my-3">
<button class="btn btn-primary btn-lg" type="submit">{{ __('Send Password Reset Link') }}</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
</body>
</html>
resources/views/auth/forgetPasswordLink.blade.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel 11 Custom Reset Password Functions</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<style type="text/css">
body{
background: #F8F9FA;
}
</style>
</head>
<body>
<section class="bg-light py-3 py-md-5">
<div class="container">
<div class="row justify-content-center">
<div class="col-12 col-sm-10 col-md-8 col-lg-6 col-xl-5 col-xxl-4">
<div class="card border border-light-subtle rounded-3 shadow-sm mt-5">
<div class="card-body p-3 p-md-4 p-xl-5">
<div class="text-center mb-3">
<a href="#!">
<img src="https://www.example.com/assets/images/logo.png" alt="BootstrapBrain Logo" width="250">
</a>
</div>
<h2 class="fs-6 fw-normal text-center text-secondary mb-4">Reset Password</h2>
<form method="POST" action="{{ route('reset.password.post') }}">
@csrf
<input type="hidden" name="token" value="{{ $token }}">
@if (Session::has('message'))
<div class="alert alert-success" role="alert">
{{ Session::get('message') }}
</div>
@endif
<div class="row gy-2 overflow-hidden">
<div class="col-12">
<div class="form-floating mb-3">
<input type="email" class="form-control @error('email') is-invalid @enderror" name="email" id="email" placeholder="name@example.com" required>
<label for="email" class="form-label">{{ __('Email Address') }}</label>
@if ($errors->has('email'))
<span class="text-danger">{{ $errors->first('email') }}</span>
@endif
</div>
</div>
<div class="col-12">
<div class="form-floating mb-3">
<input type="password" class="form-control @error('password') is-invalid @enderror" name="password" id="password" placeholder="name@example.com" required>
<label for="password" class="form-label">{{ __('Password') }}</label>
@if ($errors->has('password'))
<span class="text-danger">{{ $errors->first('password') }}</span>
@endif
</div>
</div>
<div class="col-12">
<div class="form-floating mb-3">
<input type="password" class="form-control @error('password_confirmation') is-invalid @enderror" name="password_confirmation" id="password_confirmation" placeholder="name@example.com" required>
<label for="password_confirmation" class="form-label">{{ __('Confirm Password') }}</label>
@if ($errors->has('password_confirmation'))
<span class="text-danger">{{ $errors->first('password_confirmation') }}</span>
@endif
</div>
</div>
<div class="col-12">
<div class="d-grid my-3">
<button class="btn btn-primary btn-lg" type="submit">{{ __('Reset Password') }}</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
</body>
</html>
resources/views/emails/forgetPassword.blade.php
<h1>Forget Password Email</h1>
You can reset password from bellow link:
<a href="{{ route('reset.password.get', $token) }}">Reset Password</a>
resources/views/auth/login.blade.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel 11 Custom User Login Page</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<style type="text/css">
body{
background: #F8F9FA;
}
</style>
</head>
<body>
<section class="bg-light py-3 py-md-5">
<div class="container">
<div class="row justify-content-center">
<div class="col-12 col-sm-10 col-md-8 col-lg-6 col-xl-5 col-xxl-4">
<div class="card border border-light-subtle rounded-3 shadow-sm mt-5">
<div class="card-body p-3 p-md-4 p-xl-5">
<div class="text-center mb-3">
<a href="#!">
<img src="https://www.example.com/assets/images/logo.png" alt="BootstrapBrain Logo" width="250">
</a>
</div>
<h2 class="fs-6 fw-normal text-center text-secondary mb-4">Sign in to your account</h2>
<form method="POST" action="{{ route('login.post') }}">
@csrf
@session('error')
<div class="alert alert-danger" role="alert">
{{ $value }}
</div>
@endsession
@session('message')
<div class="alert alert-success" role="alert">
{{ $value }}
</div>
@endsession
<div class="row gy-2 overflow-hidden">
<div class="col-12">
<div class="form-floating mb-3">
<input type="email" class="form-control @error('email') is-invalid @enderror" name="email" id="email" placeholder="name@example.com" required>
<label for="email" class="form-label">{{ __('Email Address') }}</label>
</div>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="col-12">
<div class="form-floating mb-3">
<input type="password" class="form-control @error('password') is-invalid @enderror" name="password" id="password" value="" placeholder="Password" required>
<label for="password" class="form-label">{{ __('Password') }}</label>
</div>
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div class="col-12">
<div class="d-flex gap-2 justify-content-between">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" name="rememberMe" id="rememberMe">
<label class="form-check-label text-secondary" for="rememberMe">
Keep me logged in
</label>
</div>
<a href="{{ route('forget.password.get') }}" class="link-primary text-decoration-none">{{ __('forgot password?') }}</a>
</div>
</div>
<div class="col-12">
<div class="d-grid my-3">
<button class="btn btn-primary btn-lg" type="submit">{{ __('Login') }}</button>
</div>
</div>
<div class="col-12">
<p class="m-0 text-secondary text-center">Don't have an account? <a href="{{ route('register') }}" class="link-primary text-decoration-none">Sign up</a></p>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
</body>
</html>
Run Laravel App:
All the required steps have been done, now you have to type the given below command and hit enter to run the Laravel app:
php artisan serve
Now you can open bellow URL on your browser:
localhost:8000/login
Forget Password Page:
Forget Password Email:
Reset Password Page:
You can also download code from git:
You Can Learn Laravel Docs