Search

How to Set Up Passwordless Login in Laravel: A Step-by-Step Guide

  • Share this:
How to Set Up Passwordless Login in Laravel: A Step-by-Step Guide

In today's digital age, online security is a top concern for both website owners and users. To combat this, many websites are adopting passwordless login systems to eliminate the need for users to remember and enter passwords. Laravel, a popular PHP web application framework, has made it easy to implement passwordless login with the help of the grosv/laravel-passwordless-login composer package.

In this tutorial, we will take you through the steps required to set up a passwordless login system with Laravel using a magic link. This system will allow users to simply enter their email or username, receive an email with a magic link, and use it to log in to the website.

Step 1: Install Laravel

This is optional; 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: Setup Database Configuration

After successfully installing the laravel app then configuring the database setup. We will open the ".env" file and change the database name, username and password in the env file.

.env

 

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=Enter_Your_Database_Name
DB_USERNAME=Enter_Your_Database_Username
DB_PASSWORD=Enter_Your_Database_Password

 

 

Step 3: Install Auth Scaffold

Laravel's laravel/ui package provides a quick way to scaffold all of the routes and views you need for authentication using a few simple commands:

 

composer require laravel/ui

 

Next, we need to generate auth scaffold with bootstrap, so let's run the below command:

 

php artisan ui bootstrap --auth

 

 

Now go to resources\views\layouts\app.blade.php  remove the bellow line.

 

    <!-- Scripts -->
    @vite(['resources/sass/app.scss', 'resources/js/app.js'])
   

 

and replaced this with the below line.

 


        crossorigin="anonymous">
        crossorigin="anonymous"></script>
     

Step 4: Install grosv/laravel-passwordless-login Package

In this step, we will install grosv/laravel-passwordless-login to generate the login url. so let's run the below command:

 


 composer require grosv/laravel-passwordless-login

Step 5: Update Login Blade File

In this step, we will update auth login blade file. in this file we will add a new Password Less Login link. so let's update the following file:

resources/views/auth/login.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') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('login') }}">
                        @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="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>

                            <div class="col-md-6">
                                <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">

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

                        <div class="row mb-3">
                            <div class="col-md-6 offset-md-4">
                                <div class="form-check">
                                    <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>

                                    <label class="form-check-label" for="remember">
                                        {{ __('Remember Me') }}
                                    </label>
                                </div>
                            </div>
                        </div>

                        <div class="row mb-0">
                            <div class="col-md-8 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Login') }}
                                </button>
                                OR
                                <button type="submit" class="btn btn-success" name="submit" value="password-less">
                                    Password Less Login
                                </button>
                                <br/>
                                @if (Route::has('password.request'))
                                    <a class="btn btn-link" href="{{ route('password.request') }}">
                                        {{ __('Forgot Your Password?') }}
                                    </a>
                                @endif
                            </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

Step 6: Update LoginController

 

<?php

namespace App\Http\Controllers\Auth;

use App\Models\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use App\Notifications\SendPasswordLessLinkNotification;

class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }
    public function login(Request $request)
    {
 
        if($request->input('submit') == 'password-less'){
            $user = $this->loginViaPasswordLessLink($request);
 
            if(!$user){
                return redirect()->route('login')
                ->withErrors(['email' => 'User with this email does not exist.'])
                ->withInput();
            }
 
            return redirect()->route('login')
                    ->withMessage('Password Less Link Sent to the registered email ID.');
        }
 
        $this->validateLogin($request);
 
        if (method_exists($this, 'hasTooManyLoginAttempts') &&
            $this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);
 
            return $this->sendLockoutResponse($request);
        }
 
        if ($this->attemptLogin($request)) {
            if ($request->hasSession()) {
                $request->session()->put('auth.password_confirmed_at', time());
            }
            return $this->sendLoginResponse($request);
        }
 
        $this->incrementLoginAttempts($request);
 
        return $this->sendFailedLoginResponse($request);
    }
    /**
     * Write code on Method
     *
     * @return response()
     */
    public function loginViaPasswordLessLink(Request $request)
    {
        $user = User::where('email', $request->input('email'))->first();
 
        if ($user) {
            $user->notify(new SendPasswordLessLinkNotification());
        }
 
        return $user;
    }
}

Step 7: Create Notification Class

 

we will update the SendPasswordLessLinkNotification.php notification for sending emails with a magic link. let's create a notification by following the command:

 

 

php artisan make:notification SendPasswordLessLinkNotification

 

 

Next update your code using this step

app/Notifications/SendPasswordLessLinkNotification.php

 

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Grosv\LaravelPasswordlessLogin\LoginUrl;
use Illuminate\Notifications\Messages\MailMessage;

class SendPasswordLessLinkNotification extends Notification
{
    use Queueable;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        $generator = new LoginUrl($notifiable);
        $generator->setRedirectUrl('/home');
        $url = $generator->generate();
 
        return (new MailMessage)
                    ->subject('Your Password Less Link!')
                    ->line('Click this link to log in!')
                    ->action('Login', $url)
                    ->line('Thank you for using our application!');
                   
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}

 

 

Run Laravel App Now:

 

php artisan serve

 

Now, Go to your web browser, type the given URL

http://localhost:8000/






 


Jahangir Alam

Jahangir Alam

I'm a full-stack website developer with a wealth of experience in creating beautiful and functional websites. I have a strong foundation in web development and am well-versed in a variety of programming languages, including HTML, CSS, JavaScript, and PHP.
With over 3 years of experience in the industry, I have worked on a wide range of projects, from small startup websites to large enterprise-level applications. He has a proven track record of delivering high-quality results, on time and within budget.
I am comfortable working with various web development frameworks such as React, Angular, and Vue.js. He has strong knowledge of the latest web development trends and best practices, which he uses to create responsive and user-friendly websites.