Может ли сервер установить куку
Что проверяют
Понимаете ли вы, откуда берутся куки и кто ими управляет: сервер через заголовок или клиент через JavaScript. Следом почти всегда спрашивают, почему фронтенд не видит сессионную куку в document.cookie и почему кука не уходит с запросом на другой домен.
Как отвечать
Да, и это основной способ. Сервер добавляет в ответ заголовок Set-Cookie, по одному на каждую куку, и браузер сохраняет её сам, без участия вашего кода. Дальше браузер прикладывает её в заголовке Cookie к подходящим запросам. Поведение задают атрибуты:
Expires/Max-Age: срок жизни. Без них кука сессионная и живёт до закрытия браузера;DomainиPath: к каким адресам кука поедет. БезDomainона привязана к точному хосту, поддомены её не получат;HttpOnly: кука недоступна изdocument.cookie, поэтому скрипт, внедрённый через XSS, её не украдёт. Поставить такую куку можно только с сервера;Secure: кука передаётся только по HTTPS;SameSite:Strict,LaxилиNone. Браузеры на Chromium без явного атрибута считают кукуLax, но полагаться на это не стоит, задавайте его явно.Noneработает только вместе сSecure.
Для SPA важна связка с fetch: при запросе на другой origin кука не отправится и не сохранится, пока вы не укажете credentials: 'include', а сервер не ответит Access-Control-Allow-Credentials: true с конкретным origin вместо *. Сам заголовок Set-Cookie из ответа JavaScript прочитать не может, браузер его скрывает.
Плюсом будет префикс __Host-: такая кука обязана быть Secure, с Path=/ и без Domain, что защищает от подмены с поддомена.
Где спотыкаются
Считают, что SameSite полностью закрывает CSRF. Он сильно снижает риск, но Lax пропускает переходы по ссылке с GET, а поддомены считаются тем же сайтом, так что CSRF-токен для изменяющих запросов всё ещё уместен.
Пытаются прочитать или удалить HttpOnly-куку из JavaScript. Удалить её может только сервер, ответив той же кукой с Max-Age=0 и теми же Path и Domain.
Кладут в куку много данных. Лимит около 4 КБ на куку, и всё содержимое летит в каждом запросе к домену, включая статику.