Skip to content

Quick Start

Jean-Marc Strauven edited this page Aug 25, 2025 · 1 revision

Quick Start

This guide will get you up and running with Laravel OneClickLogin in just a few minutes.

Prerequisites

  • Laravel 11+ project
  • User authentication system in place
  • Mail configuration (for sending magic links)

Step 1: Installation

composer require grazulex/laravel-oneclicklogin
php artisan migrate

Step 2: Basic Implementation

Create a Magic Link Request Form

<!-- resources/views/auth/magic-link.blade.php -->
<form method="POST" action="{{ route('magic-link.request') }}">
    @csrf
    <div>
        <label for="email">Email Address</label>
        <input type="email" name="email" required>
    </div>
    <button type="submit">Send Magic Link</button>
</form>

Handle Magic Link Requests

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Grazulex\OneClickLogin\Facades\OneClickLogin;
use Illuminate\Support\Facades\Mail;
use App\Mail\MagicLinkMail;

class MagicLinkController extends Controller
{
    public function showRequestForm()
    {
        return view('auth.magic-link');
    }

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

        // Generate magic link
        $link = OneClickLogin::for($request->email)
            ->redirectTo('/dashboard')
            ->expiresInMinutes(15)
            ->generate();

        // Send via email
        Mail::to($request->email)->send(new MagicLinkMail($link->getUrl()));

        return back()->with('success', 'Magic link sent! Check your email.');
    }
}

Create Email Template

<?php

namespace App\Mail;

use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;

class MagicLinkMail extends Mailable
{
    public function __construct(
        public string $magicUrl
    ) {}

    public function envelope(): Envelope
    {
        return new Envelope(
            subject: 'Your Magic Login Link',
        );
    }

    public function content(): Content
    {
        return new Content(
            view: 'emails.magic-link',
        );
    }
}
<!-- resources/views/emails/magic-link.blade.php -->
<h1>Your Login Link</h1>
<p>Click the link below to log in to your account:</p>
<a href="{{ $magicUrl }}" style="background: #007bff; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;">
    Log In Now
</a>
<p><small>This link expires in 15 minutes and can only be used once.</small></p>

Set Up Routes

<?php

// routes/web.php
use App\Http\Controllers\Auth\MagicLinkController;

Route::get('/auth/magic-link', [MagicLinkController::class, 'showRequestForm'])
    ->name('magic-link.show');

Route::post('/auth/magic-link', [MagicLinkController::class, 'sendMagicLink'])
    ->name('magic-link.request');

// The consumption route is automatically registered by the package
// GET /auth/magic-link/{token} -> OneClickLogin handles authentication

Step 3: Advanced Usage

Custom User Authentication

<?php

use Grazulex\OneClickLogin\Facades\OneClickLogin;
use Grazulex\OneClickLogin\Events\MagicLinkConsumed;

// Listen for successful magic link consumption
Event::listen(MagicLinkConsumed::class, function ($event) {
    // Custom logic after successful authentication
    $user = User::where('email', $event->email)->first();
    
    // Update last login timestamp
    $user->update(['last_login_at' => now()]);
    
    // Log successful login
    Log::info('Magic link login', ['email' => $event->email]);
});

Using with API/SPA

<?php

// API Controller for SPA applications
class ApiMagicLinkController extends Controller
{
    public function generateLink(Request $request)
    {
        $request->validate([
            'email' => 'required|email|exists:users,email'
        ]);

        $link = OneClickLogin::for($request->email)
            ->redirectTo('/dashboard')
            ->expiresInMinutes(15)
            ->withMeta(['source' => 'api'])
            ->generate();

        // Instead of sending email, return the link for testing
        // In production, send via your preferred notification service
        return response()->json([
            'message' => 'Magic link generated',
            'expires_at' => $link->expires_at,
            // Don't return the actual URL in production!
            'url' => config('app.debug') ? $link->getUrl() : null
        ]);
    }

    public function consumeLink(Request $request, string $token)
    {
        $consumer = OneClickLogin::consume($token);

        if (!$consumer->isValid()) {
            return response()->json(['error' => 'Invalid or expired link'], 400);
        }

        if (!$consumer->canUse()) {
            return response()->json(['error' => 'Link already used'], 400);
        }

        $link = $consumer->consume();
        $user = User::where('email', $link->email)->first();

        // Generate API token
        $token = $user->createToken('magic-login')->plainTextToken;

        return response()->json([
            'message' => 'Login successful',
            'token' => $token,
            'user' => $user,
            'redirect_url' => $link->redirect_url
        ]);
    }
}

Rate Limiting Configuration

<?php

// config/oneclicklogin.php
return [
    'rate_limiting' => [
        'enabled' => true,
        'max_attempts' => 3,
        'decay_minutes' => 60,
    ],
    
    'cleanup' => [
        'enabled' => true,
        'frequency' => 'daily',
    ],
];

Step 4: Testing

Feature Test Example

<?php

namespace Tests\Feature;

use Tests\TestCase;
use App\Models\User;
use Grazulex\OneClickLogin\Facades\OneClickLogin;
use Illuminate\Foundation\Testing\RefreshDatabase;

class MagicLinkTest extends TestCase
{
    use RefreshDatabase;

    public function test_user_can_request_magic_link()
    {
        $user = User::factory()->create();

        $response = $this->post('/auth/magic-link', [
            'email' => $user->email
        ]);

        $response->assertSessionHas('success');
    }

    public function test_user_can_login_with_magic_link()
    {
        $user = User::factory()->create();
        
        $link = OneClickLogin::for($user->email)
            ->redirectTo('/dashboard')
            ->generate();

        $response = $this->get($link->getUrl());

        $response->assertRedirect('/dashboard');
        $this->assertAuthenticatedAs($user);
    }
}

Step 5: Production Considerations

Security Best Practices

<?php

// config/oneclicklogin.php
return [
    // Short expiration times
    'ttl_minutes' => 10,
    
    // Enable rate limiting
    'rate_limiting' => [
        'enabled' => true,
        'max_attempts' => 3,
    ],
    
    // Use signed URLs
    'signed_urls' => true,
    
    // Enable logging
    'logging' => [
        'enabled' => true,
        'channel' => 'security',
    ],
];

Performance Optimization

<?php

// Schedule cleanup in app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
    $schedule->command('magic-link:cleanup')->daily();
}

Next Steps

Now that you have the basics working:


πŸ’‘ Quick Links: Home | Installation | Quick Start | API Reference | Examples | FAQ

πŸ”— Version: v1.0.x | License: MIT | Maintained by: Grazulex

πŸ“š Laravel OneClickLogin

Getting Started

Usage Guide

Examples

Support


πŸš€ Quick Actions

# Install
composer require grazulex/laravel-oneclicklogin

# Setup
php artisan vendor:publish --provider="Grazulex\OneClickLogin\OneClickLoginServiceProvider"
php artisan migrate

# Generate link
php artisan magic-link:generate user@example.com

πŸ“ž Support

Clone this wiki locally