Передача аутентификационного токена через cookie в связке с Iron строится вокруг идеи защищённого контейнера, в котором данные не просто подписываются, а полностью шифруются и проверяются на целостность. В отличие от классического подхода с JWT в открытом виде, здесь содержимое сессии недоступно клиенту и может быть восстановлено только сервером при наличии секретного ключа.
Библиотека Iron реализует механизм sealing/unsealing — упаковки данных в зашифрованную строку и последующего безопасного извлечения.
Основные свойства:
Фактически Iron превращает объект сессии в строку, пригодную для хранения в cookie, при этом исключая возможность подделки на стороне клиента.
Обычно токен представляет собой объект с минимально необходимыми данными:
Пример структуры:
const session = {
userId: "u12345",
role: "admin",
createdAt: Date.now()
};
Перед сохранением в cookie этот объект проходит процедуру sealing:
import Iron from '@hapi/iron';
const password = process.env.COOKIE_SECRET;
const sealed = await Iron.seal(session, password, Iron.defaults);
Результат — строка, содержащая зашифрованный payload и контроль целостности.
После формирования sealed-значения оно отправляется клиенту через заголовок Set-Cookie.
Пример в Node.js (Express):
res.setHeader('Set-Cookie', `session=${sealed}; HttpOnly; Secure; SameSite=Strict; Path=/`);
Ключевые параметры cookie:
С точки зрения клиента cookie становится непрозрачным контейнером, который нельзя прочитать или модифицировать без потери валидности.
При каждом запросе сервер получает cookie и выполняет обратную операцию — unseal.
import Iron from '@hapi/iron';
const sealed = req.cookies.session;
const session = await Iron.unseal(sealed, password, Iron.defaults);
Если данные были изменены вручную, либо повреждены — операция завершится ошибкой. Это автоматически блокирует поддельные сессии без дополнительных проверок.
После восстановления объект сессии используется для авторизации пользователя:
req.user = session.userId;
req.role = session.role;
Важный аспект — синхронизация срока жизни cookie и логики сессии.
Cookie может управляться через:
Max-Age — абсолютное время жизниExpires — дата истеченияПример:
res.setHeader(
'Set-Cookie',
`session=${sealed}; Max-Age=3600; HttpOnly; Secure; SameSite=Strict`
);
Даже если sealed-данные корректны, истёкший cookie считается недействительным.
В системах с высокой нагрузкой применяется периодическая ротация sealed-токена:
const session = await Iron.unseal(req.cookies.session, password, Iron.defaults);
session.lastActivity = Date.now();
const renewed = await Iron.seal(session, password, Iron.defaults);
res.setHeader('Set-Cookie', `session=${renewed}; HttpOnly; Secure; SameSite=Strict`);
Это позволяет ограничивать риск повторного использования старых токенов и снижает вероятность атак на основе перехвата.
Использование Iron не отменяет необходимость корректной конфигурации cookie. Основные угрозы и меры защиты:
Перехват трафика
XSS-атаки
CSRF
Подмена cookie
Утечка секретного ключа
При использовании Iron в cookie клиентская сторона полностью лишена логики интерпретации токена. Вся модель выглядит как:
Это создаёт централизованную модель доверия, где cookie выступает только как транспорт.
Частые проблемы при внедрении:
Неверный secret
Смена конфигурации Iron
Отсутствие обработки исключений
Пример обработки:
try {
const session = await Iron.unseal(cookie, password, Iron.defaults);
req.user = session.userId;
} catch (err) {
res.setHeader('Set-Cookie', 'session=; Max-Age=0');
}
Несмотря на возможность хранения сложных объектов, в sealed-cookie рекомендуется помещать только минимальный набор данных:
Всё остальное подгружается из базы данных при необходимости. Это уменьшает:
В распределённых системах важно учитывать, что Iron не предполагает шаринг состояния между сервисами. Все узлы должны иметь доступ к одному и тому же secret.
При необходимости используется:
Даже при перехвате sealed-cookie злоумышленник не может:
Однако возможен replay-attack, если не предусмотрены:
Работа с Iron и cookie формирует замкнутый цикл:
Эта схема позволяет держать логику аутентификации на сервере, минимизируя доверие к клиенту и исключая необходимость хранения открытых токенов в браузере.