Laravel User Login Password Recovery by Email : A Step-by-Step Guide

The blog post "Laravel User Login and Password Recovery: A Step-by-Step Guide" walks you through the process of setting up secure user authentication and password recovery by email in Laravel. Covering topics such as configuring the database of reset_password, customizing login views and controllers, and implementing password reset functionality, this guide ensures a comprehensive understanding. With practical tips on testing and enhancing security measures, the blog aims to empower readers to implement these features effectively in their Laravel applications.
STEP1 - open .env file for email SMTP setup :
To set up SMTP in your Laravel application using the .env file, you need to configure the following variables related to your email provider. Below is an example .env file snippet for setting up SMTP with some common email service providers:
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com // here use gmail.com
MAIL_PORT=587
MAIL_USERNAME=sndp@gmail.com // write your email
MAIL_PASSWORD=your_email_app_password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="sndp@gmail.com" // write your email
MAIL_FROM_NAME="${APP_NAME}"
Note :
- MAIL_MAILER: Set to smtp to indicate you're using SMTP.
- MAIL_HOST: The SMTP server host address (e.g., smtp.example.com).
- MAIL_PORT: The port for the SMTP server (common ports are 587 for TLS and 465 for SSL).
- MAIL_USERNAME: Your email address.
- MAIL_PASSWORD: Your email password or an app-specific password.
- MAIL_ENCRYPTION: The encryption protocol (tls or ssl)
Clear Config Cache:
After making changes to your .env file, run the following Artisan command to clear the configuration cache:
php artisan config:cache
STEP2 - Generate the Controller:
Run the following Artisan command to generate the controller:
php artisan make:controller ForgotPasswordController
STEP3 - Make a Model:
Laravel already provides a default Database Table Which name is password_resets table . Storing user emails and generating tokens. here email column make is primary key.
Make Model for password_resets table :
Code - php artisan make:model PasswordReset
Edit the Model:
Open the generated PasswordReset.php model file located in the app→Models→ directory.
Model Code :
protected $table = 'password_resets'; // table name and model name are different
public $timestamps = "false"; // Disable timestamps for this model
protected $primaryKey = "email"; // Set 'email' as the primary key
protected $fillable = [
'email',
'token',
'created_at',
];
STEP 3 - Make a view for forget password:
Create a "Forget Password" page showcasing an input box and a password reset button. Users enter their correct email and click the reset button to initiate the process.
View name - forget-password.blade.php
HTML code :
@if(session('error'))
<div class="alert alert-danger">
{{ session('error') }}
</div>
@endif
@if(session('success'))
<div class="alert alert-success">
{{ session('success') }}
</div>
@endif
<form action="{{route('forgetPassword')}}" method="POST">
@csrf
<div class="form-group">
<label for="email">Email</label>
<input type="email" id="email" name="email" placeholder="Enter Email id" class="form-control">
@error('email')
<p class="text-danger">{{$message}}</p>
@enderror
</div>
<div class="form-group row mb-0">
<a href="{{url('login')}}">Login </a>
</div>
<br>
<input type="submit" name="submit" value="Forgot Password" class="btn btn-primary">
</form>
Route : Open View.php file from Route directory and Create Two Route get and post for this page.
import - use App\Http\Controllers\ForgotPasswordController;
// forgot password page route
Route::get('forget-Password',[ForgotPasswordController::class,'forgotPasswordLoad']);
Route::post('forget-Password',[ForgotPasswordController::class,'forgotPassword'])->name('forgetPassword');
STEP 4 - Open the Login Blade View:
Open the login.blade.php file located in the resources→views→ directory.
Add Anchor Tag for Forgotten Password:
Inside the login form, add an anchor tag (<a>) with an href attribute pointing to the route or URL where users can initiate the password recovery process. This is often a "Forgot Password" page.
Add HTML Code :
<a href="{{url('/forget-Password')}}"> Forgot Your Password? </a>
STEP 5 - Open : ForgotPasswordController
Open ForgotPasswordController.php file located in the app→Http→Controllers directory.
First Route function : for view load
public function forgotPasswordLoad()
{
return view('forget-password');
}
2nd Route function : for check email, send email with link etc.
Import bellow lines of controller :
use App\Models\passwordReset; // this is model import
use Illuminate\Support\Facades\Mail; // Import the Mail facade for sending emails
use Illuminate\Support\Facades\URL; //Import the URL facade for generating URLs, especially signed routes
use Illuminate\Support\Carbon; // Import the Carbon class for handling date and time
use Illuminate\Support\Str; // Import the Str class for string manipulation, including generating random strin
use App\Models\User; // this is user model where user all details store
public function forgotPassword(Request $request)
{
try {
// Check if the user with the provided email exists
$user = User::where('email', $request->email)->get();
if (count($user) > 0) {
// Generate a random token
$token = Str::random(40);
// Build the password reset URL
$domain = URL::to('/');
$url = $domain . '/reset-password?token=' . $token;
// Prepare data for the email template
$data['url'] = $url;
$data['email'] = $request->email;
$data['title'] = "Forget password reset";
$data['body'] = "Please click the link below to reset your password.";
// Send the password reset email
Mail::send('forgotPasswordMail', ['data' => $data], function ($message) use ($data) {
$message->to($data['email'])->subject($data['title']);
});
// Get the current date and time
$dateTime = Carbon::now()->format('Y-m-d H:i:s');
// Update or insert the password reset token in the database
PasswordReset::updateOrInsert(
['email' => $request->email],
[
'email' => $request->email,
'token' => $token,
'created_at' => $dateTime,
]
);
return back()->with('success', 'Please check your email address for the password reset link.');
} else {
return back()->with('error', 'Email does not exist.');
}
} catch (\Exception $e) {
return back()->with('error', $e->getMessage());
}
}
Make a view - forgotPasswordMail.blade.php
This view page send user email for changing password.
HTML CODE :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Forgot Password</title>
</head>
<body>
<h2>{{ $data['title'] }}</h2>
<p>{{ $data['body'] }}</p>
<p><a href="{{ $data['url'] }}">Reset Password</a></p>
<p>If you didn't request a password reset, please ignore this email.</p>
<p>Thank you,<br>
Your Application Team</p>
</body>
</html>
Note: Currently, a password reset link is sent via email. Upon clicking the link, users access a view to set a new password by entering and confirming it. Upon clicking 'Reset Password,' the updated password is securely stored in the database.
Make Two Route for load view page and store password :
// for reset password
Route::get('reset-password',[ForgotPasswordController::class,'resetPasswordLoad']); // load reset page
Route::post('reset-password',[ForgotPasswordController::class,'resetPassword'])->name('resetPassword'); // store password
Open Controlller (ForgotPasswordController) :
import this line for make hash password - use Illuminate\Support\Facades\Hash;
// load page condition base if user change URL any character , page redirect 400 page not found
public function resetPasswordLoad(Request $request)
{
// Retrieve the password reset data based on the token
$resetData = passwordReset::where('token',$request->token)->get();
if(isset($request->token) && count($resetData) >0 )
{
$user = User::where('email',$resetData[0]['email'])->get();
// Pass the user data to the 'reset_password' view
return view('reset_password',compact('user'));
}else
{
// Redirect to a 404 view if the token is invalid or not found
return view('404');
}
}
For post method password store :
public function resetPassword(Request $request)
{
// Validate the incoming request data
$request ->validate([
'password' => 'required | min:6|confirmed',
]);
// Find the user in the database based on the provided ID
$user = User::find($request->id);
// Update the user's password with the hashed new password
$user ->password = Hash::make($request->password);
$user->save();
// Delete the password reset entry for the user's email from the PasswordReset table
passwordReset::where('email', $user->email)->delete();
return "<h2>Password reset successfully</h2>";
}
Make view : 404 not found
view name - 404.blade.php
code :
<h2>404 page is expired</h2>
Make view : reset password view
view name - reset_password.blade.php
Code :
@if(session('error'))
<div class="alert alert-danger">
{{ session('error') }}
</div>
@endif
<form action="{{route('resetPassword')}}" method="POST">
@csrf
<input type="hidden" name="id" value="{{$user[0]['id']}}">
<div class="form-group">
<label for="password">Enter Password</label>
<input type="password" id="password" name="password" placeholder="Enter password" class="form-control">
@error('password')
<p class="text-danger">{{$message}}</p>
@enderror
</div>
<div class="form-group">
<label for="passwords">Re-Enter Password</label>
<input type="password" id="passwords" name="password_confirmation" placeholder="ReEnter password" class="form-control">
@error('password')
<p class="text-danger">{{$message}}</p>
@enderror
</div>
<br>
<input type="submit" name="submit" value="Reset Password" class="btn btn-primary">
</form>
<br>
<a href="{{route('login')}}">Login</a>

Sandipan Kr Bag
I'm a dedicated full-stack developer, entrepreneur, and the proud owner of ocec.org.in , hailing from the vibrant country of India. My passion lies in creating informative tutorials and sharing valuable tips that empower fellow artisans in their journey. With a deep-rooted love for technology, I've been an ardent enthusiast of PHP, Laravel, Angular, Vue, Node, JavaScript, jQuery, Codeigniter, and Bootstrap from their earliest days. My philosophy revolves around the values of hard work and unwavering consistency, driving me to continuously explore, create, and share my knowledge with the tech community.
* Hire MeRelated Posts

জাভাস্ক্রিপ্ট কি? এটি কেন ব্যবহার করা হয় ?

জাভাস্ক্রিপ্ট লেখার পদ্ধতি
Step-by-Step Guide a Dynamic Image Slider with HTML, CSS, and JavaScript
Search
Latest Posts
Using AOS (Animate On Scroll) in React with Tailwind CSS
1 month ago

WebkitSpeechRecognition API
2 months ago

GitHub Understanding Common Prefixes in Conventional Commits
2 months ago
Subscribe to Our Newsletter
Get the latest updates straight to your inbox.