L’authentification par lien magique est un processus où un utilisateur se connecte sans mot de passe. Il saisit simplement son adresse e-mail dans un formulaire de connexion. Ensuite, il reçoit un e-mail contenant un lien unique et sécurisé. En cliquant sur ce lien, il est automatiquement authentifié et redirigé vers l’application ou le site. Cette méthode améliore la sécurité en évitant l’usage de mots de passe vulnérables.
1. Créer le lien de connexion
Nous allons utiliser les liens temporaires de Laravel. Cela nous permettra d’invalider le lien au bout d’un certain temps.
final class SendLoginLink
{
public function handle(string $email): void
{
Mail::to(
users: $email,
)->send(
mailable: new LoginLink(
url: URL::temporarySignedRoute(
name: 'login:store',
parameters: [
'email' => $email,
],
expiration: 3600,
),
)
);
}
}
Il nous suffira juste d’appeler la méthode handle
avec l’adresse à laquelle on doit envoyer le mail.
2. Créer le mail avec le lien
Pour se faire nous allons commencer par créer le template Markdown ou Blade de notre mail.
Nous utilisons la commande make
de Laravel pour créer notre email en Markdown:
php artisan make:mail LoginLink --markdown=emails.auth.login-link
On peut par la suite, personnalisé notre mail dans le fichier template/emails/auth/login-link.blade.php
:
<x-mail::message>
# Connexion
Utilisez le bouton ci-dessous pour vous connecter à {{ config('app.name') }}.
<x-mail::button :url="$url">
Se connecter
</x-mail::button>
*Si le bouton ne marche pas, vous pouvez copier coller le lien suivant dans votre navigateur*: {{$url}}
Merci,<br>
{{ config('app.name') }}
</x-mail::message>
On va par la suite modifier notre classe créant le mail.
final class LoginLink extends Mailable
{
use Queueable, SerializesModels;
public function __construct(
public readonly string $url,
) {}
public function envelope(): Envelope
{
return new Envelope(
subject: 'Votre lien de connexion',
);
}
public function content(): Content
{
return new Content(
markdown: 'emails.auth.login-link',
with: [
'url' => $this->url,
],
);
}
public function attachments(): array
{
return [];
}
}
3. Authentifier l’utilisateur
On commence par déclarer notre route dans notre fichier routes/web.php
:
Route::get('login/{email}', LoginController::class)->middleware('signed')->name('login:store');
On créer notre controller où l’on valide la signature et on authentifie l’utilisateur.
final class LoginController
{
public function __invoke(Request $request, string $email): RedirectResponse
{
if ($request->hasValidSignature() === false) {
abort(Response::HTTP_UNAUTHORIZED);
}
$user = User::query()->where('email', $email)->firstOrFail();
Auth::login($user, $remember = true);
return new RedirectResponse(
url: route('welcome')
);
}
}