🧱 Суть
HTTP – это stateless-протокол.
Это означает:
Каждый запрос между клиентом и сервером независим от предыдущего.
Например:
Запрос 1 → Сервер
Запрос 2 → Сервер
Запрос 3 → Сервер
Сервер сам по себе не знает:
- кто отправил запрос
- был ли пользователь авторизован
- какие данные он вводил ранее
Чтобы хранить состояние пользователя, используются:
- Cookie – данные на стороне браузера
- Session – данные на стороне сервера
Схема:
Browser
|
| Cookie (session_id)
↓
Server
|
| Session data
↓
Storage
📦 Проблема
1. HTTP не хранит состояние
Например:
Пользователь вошёл в аккаунт:
POST /login
Следующий запрос:
GET /profile
Сервер должен понять:
«Это тот же пользователь или новый?»
2. Хранить данные только в Cookie небезопасно
Например:
user_id=15Пользователь может изменить значение:
user_id=999Поэтому важные данные обычно хранятся на сервере.
3. Нужно управлять временем жизни данных
Например:
- настройки интерфейса → можно хранить долго
- авторизация → ограниченное время
- временные сообщения → несколько секунд
✅ Решение
Использовать подходящий механизм:
| Данные | Где хранить |
|---|---|
| тема сайта | Cookie |
| язык интерфейса | Cookie |
| токен сессии | Cookie |
| данные авторизации | Session |
| временные данные пользователя | Session |
💻 Код
Cookie
Cookie – это небольшие данные, которые браузер сохраняет и автоматически отправляет серверу при каждом запросе.
Пример:
Browser
theme=dark
language=ru
При запросе:
GET /profile
Cookie: theme=dark
Создание Cookie
В PHP:
setcookie(
'theme',
'dark'
);Теперь браузер сохранит:
theme=darkCookie с временем жизни
По умолчанию Cookie живёт до закрытия браузера.
Можно указать срок:
setcookie(
'theme',
'dark',
time() + 3600
);Значение:
текущий момент + 1 час
Получение Cookie
Cookie попадают в:
$_COOKIEПример:
$theme = $_COOKIE['theme'] ?? null;Удаление Cookie
Чтобы удалить Cookie:
setcookie(
'theme',
'',
time() - 3600
);Идея:
установить время в прошлом → браузер удалит
Безопасные настройки Cookie
Современный вариант:
setcookie(
'token',
$token,
[
'expires' => time() + 3600,
'httponly' => true,
'secure' => true,
'samesite' => 'Strict'
]
);HttpOnly
httponly => trueЗапрещает JavaScript доступ:
document.cookieЗащищает от части XSS-атак.
Secure
secure => trueCookie отправляется только через HTTPS.
SameSite
Защищает от CSRF.
Варианты:
| Значение | Поведение |
|---|---|
| Strict | только свой сайт |
| Lax | стандартный вариант |
| None | разрешены сторонние запросы |
Session
Session – это способ хранить данные пользователя на сервере.
В Cookie обычно хранится только идентификатор:
session_id=abc123
А данные находятся на сервере:
Session storage
abc123:
{
user_id: 15,
role: admin
}
Запуск Session
Перед использованием:
session_start();Важно: session_start() должен быть вызван до вывода HTML.
Плохо:
echo "Hello";
session_start();Ошибка:
headers already sent
Запись данных в Session
Используется:
$_SESSIONПример:
session_start();
$_SESSION['user_id'] = 15;Теперь сервер помнит:
пользователь = 15
Получение данных Session
session_start();
echo $_SESSION['user_id'];Удаление данных Session
Удалить одну переменную:
unset(
$_SESSION['user_id']
);Удалить всю сессию:
session_destroy();Авторизация через Session
Типичный сценарий:
- Пользователь отправляет логин
POST /login
- Проверяем данные
if ($passwordCorrect) {
$_SESSION['user_id'] = $user['id'];
}- Открываем защищённую страницу
session_start();
if (!isset($_SESSION['user_id'])) {
exit('Unauthorized');
}Теперь сервер понимает:
Есть session → пользователь вошёл
Нет session → гость
Cookie vs Session
| Cookie | Session |
|---|---|
| хранится в браузере | хранится на сервере |
| пользователь может изменить | пользователь напрямую не видит |
| небольшой объём данных | можно хранить больше |
| отправляется с каждым запросом | доступна через session_id |
| подходит для настроек | подходит для авторизации |
Где реально используют
Cookie:
- тема сайта
- язык
- настройки интерфейса
- аналитические идентификаторы
Пример:
theme=darkSession:
- авторизация
- корзина покупок
- flash-сообщения
- временное состояние формы
Пример:
$_SESSION['cart']Flash-сообщения
Частый паттерн:
Показать сообщение один раз:
$_SESSION['message'] =
'Profile updated';После отображения:
unset(
$_SESSION['message']
);Используется для:
- уведомлений
- ошибок формы
- сообщений после редиректа
Жизненный цикл Session
Пользователь открывает сайт
↓
session_start()
↓
PHP читает session_id
↓
Находит данные Session
↓
Создаёт $_SESSION
↓
Код работает с данными
Частые ошибки
Хранить важные данные в Cookie
Плохо:
setcookie(
'role',
'admin'
);Пользователь может изменить:
role=user
↓
role=admin
Забывать session_start()
Плохо:
$_SESSION['user'];Без:
session_start();Session недоступна.
Вызывать session_start() после вывода
Плохо:
echo "Hello";
session_start();Потому что PHP уже отправил заголовки.
Хранить слишком много данных в Session
Session не должна быть заменой базе данных.
Плохо:
$_SESSION['all_users'] = $users;Лучше:
$_SESSION['user_id'] = 15;Не обновлять Session ID после входа
После успешной авторизации:
session_regenerate_id(true);Защищает от session fixation.
🎯 Вывод
- HTTP не хранит состояние между запросами
- Cookie хранят небольшие данные в браузере
- Session хранит данные пользователя на сервере
- В Cookie обычно лежит только
session_id - Авторизацию обычно делают через Session
- Cookie требуют настройки
HttpOnly,Secure,SameSite session_start()должен выполняться до любого вывода- пользовательские данные нельзя считать доверенными