Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Middle: питання на співбесіді з теми «Автентифікація»

Питання з реальних співбесід з відповідями: Laravel і PHP, бази даних, JavaScript і фронтенд, Git, Docker, API, безпека й архітектура. Тими самими темами, що й тести.

4 питання

Це різні рівні автентифікації:

  • Breeze - стартовий набір UI: реєстрація/вхід/скидання пароля на Blade+Livewire або React/Vue. Для швидкого старту.
  • Fortify - headless-бекенд автентифікації (без UI): логіка реєстрації, 2FA, скидання пароля. Під ним працює Breeze/Jetstream.
  • Sanctum - легка автентифікація для SPA (через cookie) та простих API-токенів. Дефолт для більшості API.
  • Passport - повноцінний OAuth2-сервер: видача access/refresh токенів стороннім клієнтам. Обирають, коли потрібен саме OAuth2.

Правило: SPA чи мобільний застосунок → Sanctum; «увійти через наш сервіс» для третіх сторін → Passport.

Докладніше в документації: Sanctum

Sanctum дає два режими:

1. API-токени - модель випускає токен, який клієнт шле в заголовку Authorization: Bearer ...:

$token = $user->createToken('mobile', ['posts:read'])->plainTextToken;

Route::middleware('auth:sanctum')->get('/user', fn (Request $r) => $r->user());

2. SPA-автентифікація - для односторінкових застосунків на тому ж домені використовує звичайні сесійні cookie + CSRF (без зберігання токенів у JS, що безпечніше).

Токени підтримують abilities (scopes): $user->tokenCan('posts:read'). Трейт HasApiTokens додає tokens()-зв'язок і createToken().

Докладніше в документації: Sanctum: API-токени

Автентифікація в Laravel тримається на двох поняттях з config/auth.php.

  • Гард визначає, як користувача впізнають у запиті: session - за сесією й cookie, sanctum - ще й за токеном у заголовку.
  • Провайдер визначає, звідки користувача беруть: зазвичай Eloquent-модель User чи таблиця бази.
'guards' => [
    'web'   => ['driver' => 'session', 'provider' => 'users'],
    'admin' => ['driver' => 'session', 'provider' => 'admins'],
],
'providers' => [
    'users'  => ['driver' => 'eloquent', 'model' => App\Models\User::class],
    'admins' => ['driver' => 'eloquent', 'model' => App\Models\Admin::class],
],

Коли другий гард виправданий: коли це справді інші люди в іншій таблиці - адміністратори окремо від клієнтів, з окремим входом і сесією.

Route::middleware('auth:admin')->group(fn () => /* ... */);

Auth::guard('admin')->attempt($credentials);

Коли не потрібен: якщо різниця лише в правах. «Адмін - теж користувач, але з роллю» - це авторизація (ролі, політики), а не другий гард. Зайвий гард подвоює логіку входу, скидання пароля й верифікації пошти.

Докладніше в документації: Доступ до конкретних гардів

Обмежити кількість невдалих спроб - за ключем, що поєднує email та IP.

public function authenticate(): void
{
    $key = Str::transliterate(Str::lower($this->input('email'))) . '|' . $this->ip();

    if (RateLimiter::tooManyAttempts($key, 5)) {
        throw ValidationException::withMessages([
            'email' => __('auth.throttle', ['seconds' => RateLimiter::availableIn($key)]),
        ]);
    }

    if (! Auth::attempt($this->only('email', 'password'))) {
        RateLimiter::hit($key);
        throw ValidationException::withMessages(['email' => __('auth.failed')]);
    }

    RateLimiter::clear($key);
}

Чому саме такий ключ:

  • Лише IP - заблокує цілий офіс за NAT, а зловмисник із сотнею адрес обійде.
  • Лише email - будь-хто зможе заблокувати вхід чужому акаунту, просто вводячи неправильний пароль.
  • Email + IP гальмує перебір конкретного акаунта з конкретної адреси.

Що ще допомагає:

  • однакове повідомлення «Невірний email або пароль» - щоб не підказувати, які email зареєстровані;
  • не блокувати акаунт назавжди після N спроб - це інструмент для атаки на доступність;
  • двофакторна автентифікація, після якої перебір пароля сам по собі нічого не дає.

Стартові набори Laravel 13 вже обмежують спроби входу. Якщо застосунок за проксі (Cloudflare), перевірте довірені проксі - інакше всі запити матимуть IP проксі.

Докладніше в документації: Обмеження спроб входу