🧱 Суть

HTTP – это stateless-протокол.

Это означает:

Каждый запрос между клиентом и сервером независим от предыдущего.

Например:

Запрос 1 → Сервер
Запрос 2 → Сервер
Запрос 3 → Сервер

Сервер сам по себе не знает:

  • кто отправил запрос
  • был ли пользователь авторизован
  • какие данные он вводил ранее

Чтобы хранить состояние пользователя, используются:

  • Cookie – данные на стороне браузера
  • Session – данные на стороне сервера

Схема:

Browser
   |
   | Cookie (session_id)
   ↓
Server
   |
   | Session data
   ↓
Storage

📦 Проблема

1. HTTP не хранит состояние

Например:

Пользователь вошёл в аккаунт:

POST /login

Следующий запрос:

GET /profile

Сервер должен понять:

«Это тот же пользователь или новый?»

Например:

user_id=15

Пользователь может изменить значение:

user_id=999

Поэтому важные данные обычно хранятся на сервере.

3. Нужно управлять временем жизни данных

Например:

  • настройки интерфейса → можно хранить долго
  • авторизация → ограниченное время
  • временные сообщения → несколько секунд

✅ Решение

Использовать подходящий механизм:

ДанныеГде хранить
тема сайтаCookie
язык интерфейсаCookie
токен сессииCookie
данные авторизацииSession
временные данные пользователяSession

💻 Код

Cookie – это небольшие данные, которые браузер сохраняет и автоматически отправляет серверу при каждом запросе.

Пример:

Browser

theme=dark
language=ru

При запросе:

GET /profile
Cookie: theme=dark

В PHP:

setcookie(
    'theme',
    'dark'
);

Теперь браузер сохранит:

theme=dark

По умолчанию Cookie живёт до закрытия браузера.

Можно указать срок:

setcookie(
    'theme',
    'dark',
    time() + 3600
);

Значение:

текущий момент + 1 час

Cookie попадают в:

$_COOKIE

Пример:

$theme = $_COOKIE['theme'] ?? null;

Чтобы удалить Cookie:

setcookie(
    'theme',
    '',
    time() - 3600
);

Идея:

установить время в прошлом → браузер удалит

Современный вариант:

setcookie(
    'token',
    $token,
    [
        'expires' => time() + 3600,
        'httponly' => true,
        'secure' => true,
        'samesite' => 'Strict'
    ]
);

HttpOnly

httponly => true

Запрещает JavaScript доступ:

document.cookie

Защищает от части XSS-атак.

Secure

secure => true

Cookie отправляется только через 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

Типичный сценарий:

  1. Пользователь отправляет логин
POST /login
  1. Проверяем данные
if ($passwordCorrect) {
 
    $_SESSION['user_id'] = $user['id'];
 
}
  1. Открываем защищённую страницу
session_start();
 
if (!isset($_SESSION['user_id'])) {
    exit('Unauthorized');
}

Теперь сервер понимает:

Есть session → пользователь вошёл
Нет session → гость
CookieSession
хранится в браузерехранится на сервере
пользователь может изменитьпользователь напрямую не видит
небольшой объём данныхможно хранить больше
отправляется с каждым запросомдоступна через session_id
подходит для настроекподходит для авторизации

Где реально используют

  • тема сайта
  • язык
  • настройки интерфейса
  • аналитические идентификаторы

Пример:

theme=dark

Session:

  • авторизация
  • корзина покупок
  • flash-сообщения
  • временное состояние формы

Пример:

$_SESSION['cart']

Flash-сообщения

Частый паттерн:

Показать сообщение один раз:

$_SESSION['message'] =
    'Profile updated';

После отображения:

unset(
    $_SESSION['message']
);

Используется для:

  • уведомлений
  • ошибок формы
  • сообщений после редиректа

Жизненный цикл Session

Пользователь открывает сайт

        ↓

session_start()

        ↓

PHP читает session_id

        ↓

Находит данные Session

        ↓

Создаёт $_SESSION

        ↓

Код работает с данными

Частые ошибки

Плохо:

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() должен выполняться до любого вывода
  • пользовательские данные нельзя считать доверенными

🔗 Связано