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

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 appModels→ 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 resourcesviews→ 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 appHttpControllers 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>
 


Tag :

Share this article







Related Posts




0 Comments



Load more Comments

Post a Comment


helllo
Ocec Copyright text of dont't copyright our content