Get Appointment

Blog Single

Passwordless Login in Laravel Using Magic Link - Step by Step Guide

  • Vfix Technology
  • 24 Aug 2025
  • Laravel
  • 206 Views

In modern applications, user experience and security go hand in hand. Many developers are now moving toward passwordless login systems that allow users to authenticate securely without remembering complex passwords.

One of the easiest ways to achieve this in Laravel is by using a Magic Link – a unique, one-time URL sent to the user’s email. Once clicked, the user is automatically logged in without needing to enter a password.

In this tutorial, we’ll build a passwordless login system in Laravel using the Maize Laravel Magic Login package.

Step 1: Install Laravel

First, create a fresh Laravel project (you can skip this if you already have one):

composer create-project laravel/laravel laravel-magic-login-tutorial
cd laravel-magic-login-tutorial

Step 2: Install Laravel UI

Since we need authentication scaffolding, install Laravel UI:

composer require laravel/ui
php artisan ui bootstrap --auth
npm install && npm run dev

This gives you login, registration, and basic auth setup.

Step 3: Install Laravel Magic Login Package

Next, install the Maize Laravel Magic Login package:

composer require maize-tech/laravel-magic-login

You can publish the config and migration files and run the migrations with:

php artisan magic-login:install

Step 4: Create Controller

Now, create a controller to handle magic link requests.
File: app/Http/Controllers/MagicLinkController.php

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Maize\MagicLogin\Facades\MagicLink;

class MagicLinkController extends Controller
{
    public function loginPage()
    {
        return view('login');
    }

    public function sendMagicLink(Request $request)
    {
        $request->validate(['email' => 'required|email']);

        $user = User::where('email', $request->email)->first();

        if (! $user) {
            return back()->withErrors([
                'email' => 'This email address is not registered in our system.',
            ]);
        }

        // Generate and send magic link (expires in 60 minutes)
        MagicLink::make(
            authenticatable: $user,
            expiration: 60,
            notify: true
        );

        return back()->with('success', 'We’ve sent you a magic login link. Check your email!');
    }
}

Step 5: Define Routes

Open routes/web.php and add:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\MagicLinkController;
use Maize\MagicLogin\Facades\MagicLink;

Route::get('/', function () {
    return view('welcome');
});

Auth::routes();

Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');

// Passwordless Login Routes
Route::get('/password-less-login', [MagicLinkController::class, 'loginPage'])->name('magic.login');
Route::post('/magic-link', [MagicLinkController::class, 'sendMagicLink'])->name('magic.send');

// Register package routes
MagicLink::route();

Step 6: Configure Redirect

Inside config/magic-login.php, set the redirect URL:

'redirect_url' => '/home',
'logins_limit' => 1,

So after clicking the magic link, users are redirected to /home.

Step 7: Configure SMTP (Mailtrap Example)

In .env, add Mailtrap SMTP credentials:

MAIL_MAILER=smtp
MAIL_HOST=sandbox.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=your_mailtrap_username
MAIL_PASSWORD=your_mailtrap_password
MAIL_ENCRYPTION=tls
[email protected]
MAIL_FROM_NAME="Laravel Magic Login"

Step 8: Add Magic Login Button in Default Login Page

Open resources/views/auth/login.blade.php and add a link for passwordless login:

<hr>
<a href="{{ route('magic.login') }}" class="btn btn-primary">
    Send Magic Link
</a>

This will appear below the normal login form.

Step 9: Create Passwordless Login Page

Create resources/views/login.blade.php for users to enter their email and receive a magic link.
 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Passwordless Login</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        body {
            background-color: #f5f5f5;
        }
        .login-card {
            max-width: 400px;
            padding: 2rem;
            margin: 5% auto;
            background: #fff;
            border-radius: 0.5rem;
            box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.1);
        }
    </style>
</head>

<body>
    <div class="login-card text-center">
        @if ($errors->any())
            <div class="alert alert-danger alert-dismissible fade show" role="alert">
                @foreach ($errors->all() as $error)
                    <li>{{ $error }}</li>
                @endforeach
                <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
            </div>
        @endif

        @if (session('success'))
            <div class="alert alert-success alert-dismissable">
                <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                <strong>{{ session('success') }}</strong>
            </div>
        @endif

        <h4 class="mb-3">Login with Magic Link</h4>
        <p class="text-muted mb-4">Enter your email to receive a login link</p>

        <form method="post" action="{{ route('magic.send') }}">
            @csrf
            <div class="mb-3 text-start">
                <label for="email" class="form-label">Email address</label>
                <input type="email" class="form-control" name="email" placeholder="[email protected]" required>
            </div>
            <button type="submit" class="btn btn-primary w-100">Send Magic Link</button>
        </form>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</body>

</html>

Final Result

✅ The user can now choose between:

  • Logging in with email & password (default Laravel login).

  • Logging in with passwordless Magic Link via email.

Once the user clicks the email link, they’re redirected and logged into your Laravel app securely.

Conclusion

We successfully implemented passwordless authentication in Laravel using Magic Links. This method makes login easier and more secure for your users.

For more advanced features and customization, check out the package documentation:
👉 Laravel Magic Login GitHub Repository

Tags
Share :


+91 8447 525 204 Request Estimate