Сесійна аутентифікація для веб-додатків
Сесійна аутентифікація — класичний підхід: при логіні створюється запис у сховищі сесій, клієнту відправляється cookie з session_id. На кожному запиті сервер шукає сесію за ID та відновлює контекст користувача. Stateful — стан зберігається на сервері. Надійна, проста у впровадженні, легко відкликається.
Коли сесії краще за JWT
Сесії переважно для:
- Традиційних веб-додатків із SSR (Blade, Twig, ERB)
- Коли потрібен миттєвий logout (не чекаємо спливання токена)
- Зберігання великих даних стану без передачі у cookies
- Додатків з обмеженою кількістю користувачів
JWT переважно для:
- API, які споживають мобільні додатки
- Мікросервісної архітектури
- Горизонтального масштабування без централізованого сховища сесій
Laravel Session
// config/session.php — критичні налаштування
return [
'driver' => env('SESSION_DRIVER', 'redis'), // redis/database/file
'lifetime' => 120, // хвилини
'expire_on_close' => false, // сесія переживає закриття браузера
'encrypt' => true, // шифрування даних сесії
'secure' => true, // cookie тільки через HTTPS
'http_only' => true, // недоступна для JS
'same_site' => 'lax', // CSRF-захист
'domain' => '.example.com', // для поддоменів
];
Redis як сховище сесій — масштабуєме і швидко. Без Redis при кількох серверах у користувачів будуть «вилети» при балансуванні:
# .env
SESSION_DRIVER=redis
REDIS_SESSION_DB=1 # окрема БД Redis для сесій
Auth::login та Remember Me
public function login(LoginRequest $request)
{
$credentials = $request->only('email', 'password');
$remember = $request->boolean('remember');
if (!Auth::attempt($credentials, $remember)) {
throw ValidationException::withMessages([
'email' => [trans('auth.failed')],
]);
}
$request->session()->regenerate(); // запобігає Session Fixation
return redirect()->intended('/dashboard');
}
public function logout(Request $request)
{
Auth::logout();
$request->session()->invalidate(); // видаляє сесію
$request->session()->regenerateToken(); // новий CSRF token
return redirect('/');
}
Remember me працює через довгоживущий cookie з хешем токена — Laravel автоматично відновлює сесію при наступному візиті.
Session Fixation та CSRF
Session Fixation: атакуючий підсовує жертві session_id до логіну, після логіну отримує доступ до її сесії. Захист — session()->regenerate() одразу після успішного логіну. Laravel робить це автоматично.
CSRF: для всіх форм обов'язковий @csrf (Blade) або X-CSRF-Token заголовок для AJAX. Laravel перевіряє токен через VerifyCsrfToken middleware.
// Axios — автоматично додає CSRF token
import axios from 'axios';
axios.defaults.withCredentials = true;
axios.defaults.headers.common['X-CSRF-TOKEN'] = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
// Fetch API — cookies надсилаються з credentials: 'include'
const res = await fetch('/api/user', {
credentials: 'include',
headers: { 'X-CSRF-TOKEN': getCsrfToken() },
});
Управління кількома пристроями
// Отримуємо всі активні сесії користувача
$sessions = DB::table('sessions')
->where('user_id', auth()->id())
->orderByDesc('last_activity')
->get()
->map(fn($s) => [
'id' => $s->id,
'ip' => $s->ip_address,
'user_agent' => $s->user_agent,
'last_active' => Carbon::createFromTimestamp($s->last_activity)->diffForHumans(),
'is_current' => $s->id === request()->session()->getId(),
]);
// Завершити всі сесії крім поточної
public function logoutOtherDevices(Request $request)
{
Auth::logoutOtherDevices($request->input('password'));
return redirect('/settings/sessions')
->with('status', 'Інші сесії завершені');
}
Зберігання сесій у базі даних
php artisan session:table
php artisan migrate
// config/session.php
'driver' => 'database',
'table' => 'sessions',
Таблиця sessions: id, user_id (nullable), ip_address, user_agent, payload (зашифровано), last_activity.
Індекс на user_id обов'язковий для запиту «всі сесії користувача». Очищення застарілих сесій:
php artisan session:gc # або через Scheduler
SPA + Laravel Sanctum (Cookie-Based)
Для SPA, де фронтенд та API на одному домені — Sanctum у режимі cookie переважніший за JWT:
// Ініціалізація CSRF
// Клієнт: GET /sanctum/csrf-cookie — встановлює XSRF-TOKEN cookie
// Після цього всі POST/PUT/DELETE запити автоматично включають токен
Route::middleware('auth:sanctum')->get('/api/user', fn(Request $r) => $r->user());
Sanctum в режимі cookie = сесії з додатковою захистом. API токени — окрема функція Sanctum для мобільних клієнтів.
Терміни
Сесійна аутентифікація з Redis, remember me, CSRF-захистом, logout зі всіх пристроїв: 1–2 дні. З UI управління сесіями, аудит-логом входів (IP, пристрій, геолокація), виявленням підозрілих входів: 3–5 днів.







