-
-
Notifications
You must be signed in to change notification settings - Fork 2
Quick Start
Jean-Marc Strauven edited this page Aug 25, 2025
·
1 revision
This guide will get you up and running with Laravel OneClickLogin in just a few minutes.
- Laravel 11+ project
- User authentication system in place
- Mail configuration (for sending magic links)
composer require grazulex/laravel-oneclicklogin
php artisan migrate
<!-- 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>
<?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.');
}
}
<?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>
<?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
<?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]);
});
<?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
]);
}
}
<?php
// config/oneclicklogin.php
return [
'rate_limiting' => [
'enabled' => true,
'max_attempts' => 3,
'decay_minutes' => 60,
],
'cleanup' => [
'enabled' => true,
'frequency' => 'daily',
],
];
<?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);
}
}
<?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',
],
];
<?php
// Schedule cleanup in app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
$schedule->command('magic-link:cleanup')->daily();
}
Now that you have the basics working:
- Configuration - Detailed configuration options
- API Reference - Complete API documentation
- Examples - More real-world examples
- Console Commands - CLI tools and helpers
π‘ Quick Links: Home | Installation | Quick Start | API Reference | Examples | FAQ
π Version: v1.0.x | License: MIT | Maintained by: Grazulex
Laravel OneClickLogin v1.0.x | GitHub | MIT License | Maintained by Grazulex
π‘ Quick Links: Home | Installation | Quick Start | API Reference | Examples | FAQ
# 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