992 views

1 Answer

answered by

Laravel 11 - Login with Email OTP

https://youtu.be/Aat3AhB-99s

Step 1: create Project

composer create-project laravel/laravel LaravelLoginWithOTP

cd LaravelLoginWithOTP

Open in any text editor like vscode, sublime text, notepad, notepad ++ etc.

Step 2 : Generate login / registration scaffolding

composer require laravel/ui

// Generate login / registration scaffolding...

php artisan ui bootstrap --auth

//Before compiling your CSS, install your project's frontend dependencies using the Node package manager (NPM):

npm install

Step 3 : configure database in .env file

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravelloginwithotp
DB_USERNAME=root
DB_PASSWORD=admin@123

Step 4 : add one column in users table using migration table (filename is 0001_01_01_000000_create_users_table.php).

Schema::create('users', function (Blueprint $table) {
            .................
            $table->integer('otp')->nullable();
            .................
        });

# add "otp" in Model page i.e User.php

protected $fillable = [
        ......
        ......
        'otp',
    ];

Step 5 : now run the migration and create database & tables.

php artisan migrate

Step 6 : Now start the service in two tabs and check the application.

//Once the dependencies have been installed using npm install, you can compile your SASS files to plain CSS using Vite. The npm run dev command will process the instructions in your vite.config.js file. Typically, your compiled CSS will be placed in the public/build/assets directory:

php run dev

# for running the server.

php artisan serve

Now open in browser and test the pages.

http://127.0.0.1:8000

Step 7 : now register with the link

http://127.0.0.1:8000/register

and test login with registered login credentials.

Step 8 : Add link to login with OTP page in login.blade.php

....................................
....................................
                               @if (Route::has('password.request'))
                                    <a class="btn btn-link" href="{{ route('password.request') }}">
                                        {{ __('Forgot Your Password?') }}
                                    </a>
                                @endif
                                <p>
                                    <a class="btn btn-link" href="{{ route('login.with.otp') }}">
                                        {{ __('Login with OTP.') }}
                                    </a>
                                </p>
....................................
....................................

Step 9 : Now create loginwithotp.blade.php page.

#resources\views\loginwithotp.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Login With OTP') }}</div>
                @if(Session::has('success'))
                    <div class="alert alert-success">
                        {{ Session::get('success') }}
                    </div>
                @endif
                @if(Session::has('error'))
                    <div class="alert alert-danger">
                        {{ Session::get('error') }}
                    </div>
                @endif
                <div class="card-body">
                    <form method="POST" action="{{ route('login.with.otp.post') }}">
                        @csrf

                        <div class="row mb-3">
                            <label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>

                            <div class="col-md-6">
                                <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>

                                @error('email')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="row mb-0">
                            <div class="col-md-8 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Send OTP') }}
                                </button>

                                @if (Route::has('password.request'))
                                    <a class="btn btn-link" href="{{ route('confirm.login.with.otp') }}">
                                        {{ __('already have OTP?') }}
                                    </a>
                                @endif
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

Step 10 : Now create controller for opt login.

php artisan make:controller OTPController

Step 11 : Now create route in web.php

Route::view('/login-with-otp', 'auth.loginwithotp')->name('login.with.otp');
Route::post('/loginwithotppost', [App\Http\Controllers\OTPController::class, 'loginwithotppost'])->name('login.with.otp.post');

Now, check the login with otp page in browser.

http://127.0.0.1:8000/loginwithotp

Step 12 : For sending email we need the gmail smtp. So, configure the app password in google myaccount.

Open, 

https://myaccount.google.com/

goto,

(left menu)->Secutiry->2-Step Verification(click on)->To continue, first verify it’s you(Provide the password for login)->click on "next" -> Click on "App passwords >" -> To create a new app specific password, type a name for it below... -> Enter app name "LaravelLoginOTP" -> Click on "Create".

Now you will get "New Generated app password"

Copy the app password and keep it safe.

example app password is: kyvplexjhqavzaps 

Step 13 : Configuration of smtp in .env file. (provide the MAIL_PASSWORD is app password (without space) we created before.)

MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME="inchirags@gmail.com"
MAIL_PASSWORD="kyvplexjhqavzaps"
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="inchirags@gmail.com"
MAIL_FROM_NAME="${APP_NAME}"

Step 14 : Add new method in controller -> OTPController.php

#call User Model in top (below of "use Illuminate\Http\Request;").

use Illuminate\Support\Facades\Auth;
use App\Models\User;
use Mail;

public function loginwithotppost(Request $request)
    {
        //dd($request);
        $request->validate([
            'email'=>'required|email|max:50',
        ]);
        $checkIsUser = User::where('email', $request->email)->first();
        if(is_null($checkIsUser) ){
            return redirect()->route('login.with.otp')->with('error','Your account is not registered with us.');
        } else {
            $otp = rand(123456, 999999);
            $userupdate = User::where('email',$request->email)->update([
                'otp' => $otp,
            ]);

            Mail::send('emails.loginWithOTPEmail',['otp'=>$otp],function($message) use($request){
                $message->to($request->email);
                $message->subject('Login with OTP - Chirags.in');
            });

            return redirect('confirm-login-with-otp')->withSuccess('Reset password link sent to your email address. Please check your Inbox/Spam Folder for reset password link.');
        }
    }

Step 15 : For email create a folder inside the 

# resources->views->emails->loginWithOTPEmail.blade.php

<h1>Login with OTP eMail</h1>
<p>Your OTP is : {{ $otp }}</p>
<p>Open the bellow link:</p>
<a href="{{ route('confirm.login.with.otp') }}">Click here for confirm login with otp page.</a>

You can take any good email template.

Step 16 : Now create two more route for confirm login and confirm login post.

Route::view('/confirm-login-with-otp', 'auth.confirmloginwithotp')->name('confirm.login.with.otp');
Route::post('/confirmloginwithotppost', [App\Http\Controllers\OTPController::class, 'confirmloginwithotppost'])->name('confirm.login.with.otp.post');

Step 17 : Create method for confirmloginwithotppost inside the OTPController.php controller.

public function confirmloginwithotppost(Request $request)
    {
        //dd($request->all());
        $request->validate([
            'email' => 'required|email',
            'otp' => 'required',
        ]);

        $checkUser = User::where('otp',$request->otp)->where('email', $request->email)->first();
        if(is_null($checkUser) ){
            return redirect()->route('confirm.login.with.otp')->with('error','OTP or Email is incorrect.');
        } else {
            $user = User::where('email',$request->email)->first();
            if($user){
                $userupdate = User::where('email',$request->email)->update([
                    'otp' =>NULL
                ]);
                Auth::login($user);
                return redirect()->route('home')->with('success','Welcome to user dashboard.');
            }
            return redirect()->back()->with('error','Login with otp failed.');
        }
    }

Step 18 : create confirmloginwithotp.blade.php page inside the "resource->views->auth" folder.

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Confirm Login With OTP') }}</div>
                @if(Session::has('success'))
                    <div class="alert alert-success">
                        {{ Session::get('success') }}
                    </div>
                @endif
                @if(Session::has('error'))
                    <div class="alert alert-danger">
                        {{ Session::get('error') }}
                    </div>
                @endif
                <div class="card-body">
                    <form method="POST" action="{{ route('confirm.login.with.otp.post') }}">
                        @csrf

                        <div class="row mb-3">
                            <label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>

                            <div class="col-md-6">
                                <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>

                                @error('email')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="row mb-3">
                            <label for="otp" class="col-md-4 col-form-label text-md-end">{{ __('OTP') }}</label>

                            <div class="col-md-6">
                                <input id="otp" type="password" class="form-control @error('otp') is-invalid @enderror" name="otp" value="{{ old('otp') }}" required>

                                @error('otp')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="row mb-0">
                            <div class="col-md-8 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Login') }}
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

Step 19 : Now open in browser and test the pages.

A. Register yourself with valid email address.

http://127.0.0.1:8000/register

B. go to Login with OTP page.

http://127.0.0.1:8000/login-with-otp

After putting the email address the submit the page. You will get an email with OTP.

C. now goto 

http://127.0.0.1:8000/confirm-login-with-otp

It will ask you the email and OTP. Provide the registered email address and OTP then click on submit. You'll be logged in now.

Thankyou :)

Most popular tags

laravel postgresql laravel-10 replication ha postgresql mongodb laravel-11 mongodb database mongodb tutorial ubuntu 24.04 lts streaming-replication mysql database laravel postgresql backup laravel login register logout database mysql php laravel 11 - login with otp valid for 10 minutes. user and admin registration user and admin login multiauth technlogy asp.net asp.net c# mysql master slave replication centos linux laravel sql server schedule backup autobackup postgresql django python haproxy load balancer install self sign ssl laravel 11 gaurds zabbix 7 how to install graylog on ubuntu 24.04 lts | step-by-step asp.net core mvc .net mvc network upload c# ssl integration sql server on ubuntu 22.04 lts mssql server ms sql server sql server user access in postgres mysql password change cent os linux configure replica laravel 11 socialite login with google account google login kubernetes (k8s) install nginx load balancer install install and configure .net 8.0 in ubuntu 24.04 lts php in iis php with iis php tutorial chirags php tutorials chirags php tutorial chirags tutorial laravel 11 guards mongodb sharding metabase business analytics metabase postgresql 16 to postgresql 17 postgresql migration letsencrypt mongodb crud rocky linux laravel custom captcha laravel 11 captcha laravel captcha mongo dll php.ini debian 12 nginx apache nextcloud gitea in ubuntu git gitea npm error node js mysql ndb cluster mysql cluster ssl oracle login register logout in python debian windows shell batch file bat file time stamp date time shopping cart in laravel centos rhel swap memeory rhel 5.5
...