Аутентификация и авторизация
Auth, guards, Gates и Policies, Sanctum, токены.
Junior Как хранятся пароли и как правильно их проверять?
Пароли хешируются bcrypt (по умолчанию) или argon2 через фасад Hash:
use Illuminate\Support\Facades\Hash;
$user->password = Hash::make('secret'); // bcrypt с salt
Hash::check('secret', $user->password); // проверка — НЕ сравнение строк!
Hash::needsRehash($user->password); // пора ли перехешировать (смена cost)
В модели User из коробки:
protected $casts = ['password' => 'hashed']; // автохеш при присвоении
Важные правила:
- пароль никогда не хранится в открытом виде и не логируется;
- сравнивать только через
Hash::check()(timing-safe); Auth::attempt()сам хеширует и сверяет — вручнуюHash::checkобычно не нужен;passwordдолжен быть в$hiddenмодели.
Политика паролей при регистрации: правило Password::min(8)->mixedCase()->numbers()->uncompromised() (проверка по haveibeenpwned).
Junior Что произойдёт, если не защитить маршрут? Как организовать роли?
Маршрут без middleware auth доступен всем — типичная ошибка новичков. Проверка в самом контроллере (if (!Auth::check())) дублируется и забывается — используют middleware:
Route::middleware('auth')->group(function () {
Route::get('/dashboard', ...);
});
Роли — простой вариант (колонка role):
Route::middleware('can:view-admin')->group(...);
Gate::define('view-admin', fn (User $u) => $u->role === 'admin');
RBAC (роли + разрешения в БД) — обычно пакет spatie/laravel-permission:
$user->assignRole('editor');
$user->givePermissionTo('publish posts');
$user->hasRole('editor'); $user->can('publish posts');
Route::middleware('role:admin|editor')->group(...);
@role('admin') ... @endrole
Граница ответственности: аутентификация — кто ты (логин), авторизация — что тебе можно (gates/policies). Не путать на собеседовании.
Junior Как работают подтверждение email, сброс пароля и remember me?
Email verification: модель реализует MustVerifyEmail, маршруты — middleware verified:
class User extends Authenticatable implements MustVerifyEmail { ... }
Route::get('/profile', ...)->middleware(['auth', 'verified']);
Laravel шлёт письмо с подписанной ссылкой (signed URL), обработчик помечает email_verified_at. Событие — можно слушать Registered / Verified.
Password reset: встроенный flow «забыл пароль»: генерируется токен (таблица password_reset_tokens), письмо со ссылкой, форма смены. Всё из коробки у Breeze/Fortify.
Remember me: Auth::attempt($credentials, remember: true) — отдельная долгоживущая cookie с токеном (колонка remember_token). При истёкшей сессии пользователь автоматически перелогинивается. Токен ротируется при каждом использовании — защита от кражи cookie.
Все три механизма не нужно писать руками — важно знать, как они устроены и как кастомизируются (уведомления toMailUsing, брокеры паролей).
Middle Как устроена аутентификация в Laravel: guards и providers?
Конфиг — config/auth.php. Две концепции:
- Guard — как пользователь аутентифицируется в запросе:
session(куки + сессия) илиtoken/sanctum(API-токен); - Provider — откуда берутся пользователи:
eloquent(модель User) илиdatabase(Query Builder).
'guards' => [
'web' => ['driver' => 'session', 'provider' => 'users'],
'api' => ['driver' => 'sanctum', 'provider' => 'users'],
],
Основные операции:
Auth::attempt(['email' => $email, 'password' => $pass]); // логин
Auth::attempt($credentials, remember: true);
Auth::user(); Auth::id(); Auth::check();
Auth::logout();
Auth::login($user); // вручную
Auth::guard('admin')->user(); // конкретный guard
Middleware auth (редирект гостей), guest. Rate limit логина — throttle / RateLimiter в Fortify/Breeze.
Стартер-киты: Breeze (Blade/Inertia/Livewire/API), Jetstream (команды, 2FA), Fortify (headless-бэкенд аутентификации).
Middle Gates и Policies: в чём разница и как применять?
Gate — простая проверка «может ли пользователь выполнить действие», обычно не привязанная к модели:
Gate::define('view-dashboard', fn (User $user) => $user->isAdmin());
Gate::allows('view-dashboard');
Gate::authorize('view-dashboard'); // или 403
Policy — набор правил для конкретной модели:
php artisan make:policy PostPolicy --model=Post
class PostPolicy
{
public function viewAny(User $user): bool { ... }
public function view(User $user, Post $post): bool { ... }
public function update(User $user, Post $post): bool
{
return $user->id === $post->user_id;
}
// before() — супер-правило: return true для админа
}
Применение:
$this->authorize('update', $post); // в контроллере
Gate::authorize('update', $post);
$post->user->can('update', $post);
Route::put('/posts/{post}', ...)->middleware('can:update,post');
@can('update', $post) <a href="...">Редактировать</a> @endcan
Ресурсные контроллеры: authorizeResource(Post::class, 'post') связывает методы контроллера с методами policy автоматически.
Middle Laravel Sanctum: что это и когда использовать вместо Passport?
Sanctum — лёгкая аутентификация для API и SPA:
- API-токены (для мобильных приложений, сторонних клиентов):
$token = $user->createToken('mobile', ['posts:read'])->plainTextToken;
// клиент: Authorization: Bearer <token>
$request->user()->tokenCan('posts:read');
- SPA-режим — stateful-аутентификация по cookie для фронта на своём домене: Sanctum выпускает CSRF-cookie (
/sanctum/csrf-cookie), дальше работает обычная сессия.
Sanctum vs Passport:
| Sanctum | Passport | |
|---|---|---|
| Сложность | минимальная | полноценный OAuth2-сервер |
| Токены | простые Bearer | OAuth2 access/refresh |
| Сценарий | свои SPA/мобильные приложения | сторонние клиенты, authorization code flow, гранты |
Правило: если не нужен полный OAuth2 (чужие приложения получают доступ к данным ваших пользователей) — берите Sanctum. Passport — когда вы сами OAuth-провайдер.