Email Magic Link for Laravel — це пакет для безпарольної автентифікації. Він дозволяє входити в систему за допомогою посилання в імейлі або одноразового коду. Пакет працює автономно або в поєднанні з Laravel Fortify і не потребує додаткових залежностей, окрім самого фреймворку.
Основні можливості пакета:
- Вхід за посиланням, кодом або обома способами — налаштовується одним параметром
mode. - Захист від автоматичних сканерів —
GET-запит з імейла лише відкриває сторінку підтвердження; токен активується виключно черезPOST-запит. - Інтеграція з Fortify без обходу захисту — користувачі з активованим TOTP перенаправляються на перевірку двофакторної автентифікації (2FA).
- Безпечне зберігання токенів — використання HMAC-SHA256, одноразове використання та захист від брутфорсу для кожного токена.
- Гнучкий API — можливість самостійно генерувати посилання та коди для відправки через SMS, push-сповіщення або власні класи
mailable. - Обмеження повторних запитів — система затримок (cooldowns), що зростають, та ліміт на кількість відправлень за годину.
- JSON-відповіді для SPA та мобільних клієнтів, а також підтримка альтернативних
guards(наприклад,admin).
# Захист від сканерів пошти
Типова проблема magic-посилань полягає в тому, що антивірусні сканери та поштові клієнти заздалегідь відкривають усі URL у повідомленні. Якщо вхід відбувається через GET-запит, сканер «спалює» одноразовий токен ще до того, як користувач відкриє лист.
Цей пакет розділяє процес на два етапи. GET-запит на /magic-link/verify/{token} лише відображає підписану сторінку підтвердження. Токен анулюється лише після явного POST-запиту з цієї сторінки, який сканери не виконують.
Аналогічний підхід застосовано і до безпеки даних. Токени та коди ніколи не зберігаються у відкритому вигляді — лише як хеш HMAC-SHA256. Система захищена від стану гонитви (race conditions), відповіді сервера однакові незалежно від існування імейла, а для кожного токена діє окремий ліміт спроб (max_attempts_per_token, за замовчуванням 5).
# Передача двофакторної автентифікації у Fortify
Якщо користувач налаштував TOTP через Fortify, підтвердження magic-посилання не логінить його автоматично. Замість цього система перенаправляє його на етап 2FA-перевірки. Це унеможливлює обхід другого фактора через клік по посиланню.
Для SPA та мобільних додатків встановіть api.enabled у значення true. У такому разі ендпоінти повертатимуть JSON із інформацією про статус автентифікації:
{ "authenticated": false, "two_factor": true, "redirect": "<challenge url>" }
# Самостійна генерація посилань та кодів
Ви можете генерувати облікові дані через фасад без автоматичного надсилання листа. Це зручно для доставки через SMS, push або власні шаблони:
use EmailMagicLink\Facades\EmailMagicLink;
$link = EmailMagicLink::issueLink($user);
$link->url; // Підписаний URL підтвердження
$link->expiresAt; // Екземпляр Carbon
$link->expiresInMinutes;
$code = EmailMagicLink::issueCode($user);
$code->code;
$code->expiresAt;
Також можна використовувати контракт EmailMagicLink\Contracts\MagicLinkIssuer. Зміна прив'язки MagicLinkAuthenticator дозволяє керувати діями після верифікації, а реалізація контракту CaptchaGuard додає CAPTCHA до форми запиту.
# Ліміти на повторне відправлення
Безпарольні входи часто провокують користувачів на спам кнопкою перевідправки. Вбудований ResendGuard застосовує прогресивну затримку (30с, потім 60с, далі 120с) та обмежує кількість відправлень до п'яти на годину. Ви можете використовувати цей механізм у власних контролерах:
use EmailMagicLink\Contracts\ResendGuard;
public function resend(Request $request): Response
{
$decision = $this->guard->attempt('custom-key');
if (! $decision->allowed) {
return back()->with('retry_after', $decision->retryAfterSeconds);
}
// Надсилання пошти…
}
Очищення протермінованих токенів виконується запланованою командою:
Schedule::command('email-magic-link:purge')->daily();
# Встановлення
Для роботи пакета потрібні PHP 8.4 та Laravel 13. Підтримка Fortify є опціональною:
composer require pushery/email-magic-link-for-laravel
php artisan email-magic-link:install
php artisan migrate
Детальна документація та інструкції доступні на GitHub.