438 views

1 Answer

answered by

Laravel 11 - Login with Email OTP

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 :)

...