Додати cookie до відповіді:
return response('Hello')->cookie('theme', 'dark', minutes: 60 * 24 * 365);
return response('Hello')->withoutCookie('theme'); // видалити
Черга cookie - коли відповіді ще немає (сервіс, middleware, слухач події):
use Illuminate\Support\Facades\Cookie;
Cookie::queue('last_seen_post', $post->id, minutes: 60);
Cookie::expire('promo_banner');
Laravel прикріпить cookie з черги до відповіді, яка буде відправлена.
Читання:
$theme = $request->cookie('theme');
Шифрування за замовчуванням. Middleware EncryptCookies шифрує й підписує всі cookie, які створює Laravel, ключем APP_KEY. Наслідки:
- клієнт не може прочитати чи підробити значення - змінене cookie просто не розшифрується, і
$request->cookie()повернеnull; - JavaScript бачить зашифрований рядок, а не значення;
- cookie, встановлене не Laravel (з JavaScript чи іншим сервісом), Laravel спробує розшифрувати й отримає
null.
Виключення з шифрування - для cookie, які має читати фронтенд чи інший сервіс:
// bootstrap/app.php
->withMiddleware(function (Middleware $middleware): void {
$middleware->encryptCookies(except: [
'theme',
'consent',
]);
})
Незашифровані cookie не можна вважати надійними: користувач змінює їх як завгодно, тож у них - лише налаштування інтерфейсу, ніколи не права чи ідентифікатори.
Атрибути безпеки (за замовчуванням з config/session.php): secure, httpOnly, sameSite. Для власних cookie їх можна передати в cookie():
cookie('theme', 'dark', 525600, path: '/', domain: null, secure: true, httpOnly: false, sameSite: 'lax');
Що пам'ятати:
- зміна
APP_KEYробить усі зашифровані cookie, включно з сесією, недійсними - користувачів розлогінить (допомагаєAPP_PREVIOUS_KEYS); - розмір: браузер обмежує cookie приблизно 4 КБ, а шифрування збільшує значення - великі дані в cookie не кладуть;
- кешування сторінок: відповідь з
Set-CookieCDN зазвичай не кешує, тож cookie на кожній сторінці ламає кеш на краю мережі.