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.
0 Comments