How to create Passwordless Authentication in Laravel 11

Passwordless authentication in Laravel 11 involves allowing users to log in without a password, typically using a magic link sent to their email or a one-time code. Here’s a detailed guide on how to implement passwordless authentication using Laravel 11.

Step-by-Step Guide

1. Setup Laravel Project

If you haven't set up your Laravel project yet, create a new Laravel project:


composer create-project laravel/laravel passwordless-auth cd passwordless-auth

2. Create Migration for Passwordless Tokens

Create a migration for storing passwordless login tokens.


php artisan make:migration create_passwordless_tokens_table

Edit the generated migration file:


// database/migrations/xxxx_xx_xx_xxxxxx_create_passwordless_tokens_table.php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreatePasswordlessTokensTable extends Migration { public function up() { Schema::create('passwordless_tokens', function (Blueprint $table) { $table->id(); $table->foreignId('user_id')->constrained()->onDelete('cascade'); $table->string('token')->unique(); $table->timestamp('expires_at'); $table->timestamps(); }); } public function down() { Schema::dropIfExists('passwordless_tokens'); } }

Run the migration:


php artisan migrate

3. Create Models

Create a model for the passwordless tokens:


php artisan make:model PasswordlessToken

Edit the generated model file:


// app/Models/PasswordlessToken.php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class PasswordlessToken extends Model { use HasFactory; protected $fillable = ['user_id', 'token', 'expires_at']; public function user() { return $this->belongsTo(User::class); } }

4. Create Routes and Controllers

Define the routes for requesting and using a passwordless login token in routes/web.php:


// routes/web.php use App\Http\Controllers\Auth\PasswordlessLoginController; Route::get('login', [PasswordlessLoginController::class, 'showLoginForm'])->name('login'); Route::post('login', [PasswordlessLoginController::class, 'sendLoginLink'])->name('login.send'); Route::get('login/{token}', [PasswordlessLoginController::class, 'login'])->name('login.token');

Create the controller:


php artisan make:controller Auth/PasswordlessLoginController

Edit the generated controller:


// app/Http/Controllers/Auth/PasswordlessLoginController.php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use App\Models\PasswordlessToken; use App\Models\User; use Carbon\Carbon; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Mail; use Illuminate\Support\Str; class PasswordlessLoginController extends Controller { public function showLoginForm() { return view('auth.login'); } public function sendLoginLink(Request $request) { $request->validate(['email' => 'required|email|exists:users,email']); $user = User::where('email', $request->email)->first(); $token = Str::random(60); $expiresAt = Carbon::now()->addMinutes(10); PasswordlessToken::create([ 'user_id' => $user->id, 'token' => $token, 'expires_at' => $expiresAt, ]); $link = route('login.token', ['token' => $token]); Mail::send('auth.emails.login', ['link' => $link], function ($message) use ($user) { $message->to($user->email); $message->subject('Your Magic Login Link'); }); return redirect()->back()->with('message', 'A magic login link has been sent to your email.'); } public function login($token) { $passwordlessToken = PasswordlessToken::where('token', $token) ->where('expires_at', '>', Carbon::now()) ->first(); if (!$passwordlessToken) { return redirect()->route('login')->withErrors(['token' => 'The login link is invalid or has expired.']); } $user = $passwordlessToken->user; Auth::login($user); $passwordlessToken->delete(); return redirect()->route('home'); } }

5. Create Email Template

Create the email template for sending the magic link:


<!-- resources/views/auth/emails/login.blade.php --> <p>Click the link below to log in:</p> <p><a href="{{ $link }}">{{ $link }}</a></p>

6. Create Login View

Create the login form view:


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

7. Configure Mail Settings

Ensure you have your mail settings configured in your .env file:


MAIL_MAILER=smtp MAIL_HOST=smtp.mailtrap.io MAIL_PORT=2525 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null MAIL_FROM_ADDRESS="hello@example.com" MAIL_FROM_NAME="${APP_NAME}"

Conclusion

By following these steps, you can implement passwordless authentication in Laravel 11. This method improves user experience by allowing users to log in without remembering a password, relying instead on a secure, time-limited magic link sent to their email. Ensure you handle the tokens securely and set appropriate expiration times to maintain security.

Post a Comment

0 Comments