Безопасное управление токенами

Управление токенами — ключевой аспект безопасности клиентских веб-приложений. В контексте Mithril это особенно важно, так как фреймворк предоставляет лёгкую структуру для построения компонентов и маршрутизации, но не накладывает строгих ограничений на хранение и обработку данных аутентификации. Основные принципы заключаются в правильном хранении, обновлении и передаче токенов.


Хранение токенов

Существует несколько способов хранения токенов на клиенте:

  1. LocalStorage Позволяет сохранять токен между сессиями. Основное преимущество — простота доступа из любого компонента. Недостаток — уязвимость к XSS-атакам, так как любой скрипт на странице может получить доступ к localStorage.

  2. SessionStorage Данные живут только в рамках текущей вкладки браузера. Подходит для токенов, которые не должны сохраняться между сессиями. Более безопасно по сравнению с localStorage, но всё ещё подвержено XSS.

  3. HTTP-only Cookies Токен сохраняется в cookie с флагом HttpOnly, что делает его недоступным для JavaScript. Этот способ наиболее безопасен против XSS, однако требует внимательного контроля CSRF-атак.

Рекомендация: предпочтительно использовать HTTP-only cookies для хранения токенов с коротким сроком действия и периодическим обновлением.


Передача токенов с запросами

Mithril предоставляет встроенный модуль m.request для работы с HTTP-запросами. Токен передается в заголовках или как cookie.

Пример передачи токена в заголовке Authorization:

m.request({
    method: "GET",
    url: "/api/user",
    headers: {
        "Authorization": `Bearer ${localStorage.getItem("authToken")}`
    }
})
.then(response => {
    console.log(response);
})
.catch(err => console.error(err));

Для cookie достаточно настроить сервер и включить опцию withCredentials:

m.request({
    method: "GET",
    url: "/api/user",
    withCredentials: true
})

Обновление токенов

Для токенов с ограниченным сроком жизни необходимо реализовать механизм refresh token. Он позволяет получать новый токен без повторного входа пользователя.

  1. Структура работы:

    • Основной токен (access token) хранится в памяти или sessionStorage.
    • Токен обновления (refresh token) хранится в HTTP-only cookie.
    • При истечении срока действия access token приложение автоматически отправляет запрос на /refresh для получения нового токена.
  2. Пример логики в Mithril:

async function secureRequest(options) {
    try {
        return await m.request(options);
    } catch (err) {
        if (err.code === 401) {
            // попытка обновления токена
            await m.request({ method: "POST", url: "/refresh", withCredentials: true });
            return m.request(options); // повторный запрос
        }
        throw err;
    }
}

Защита от XSS и CSRF

  • XSS: Любой токен, доступный через JavaScript (localStorage/sessionStorage), может быть украден вредоносным скриптом. Использование HTTP-only cookies минимизирует риск.
  • CSRF: При использовании cookies важно включать SameSite=Lax или Strict, чтобы предотвратить несанкционированные запросы с других сайтов.

Интеграция с компонентами Mithril

Компоненты Mithril легко адаптируются для работы с токенами:

const UserProfile = {
    oninit: vnode => {
        secureRequest({ method: "GET", url: "/api/user", withCredentials: true })
            .then(data => vnode.state.user = data);
    },
    view: vnode => m("div", vnode.state.user ? `Привет, ${vnode.state.user.name}` : "Загрузка...")
};

Использование централизованного запроса через secureRequest позволяет автоматически обрабатывать истекшие токены и повышает безопасность приложения без дублирования логики в каждом компоненте.


Управление токенами и маршрутизация

Mithril Router позволяет защищать маршруты на основе наличия токена:

m.route(document.body, "/", {
    "/": Home,
    "/profile": {
        onmatch: () => {
            const token = sessionStorage.getItem("authToken");
            return token ? UserProfile : m.route.set("/");
        }
    }
});

Такой подход предотвращает доступ к защищённым страницам без действительного токена и обеспечивает централизованное управление авторизацией.


Итоговые рекомендации по безопасному управлению токенами

  • Хранить токены в HTTP-only cookie для максимальной защиты.
  • Использовать короткоживущие access tokens и refresh tokens для продления сессий.
  • Централизовать обработку запросов и обновления токенов через обёртку вроде secureRequest.
  • Настраивать защиту от XSS и CSRF на клиенте и сервере.
  • Интегрировать проверку токенов с маршрутизацией Mithril для контроля доступа к компонентам.

Эти практики позволяют создавать безопасные и масштабируемые приложения на Mithril, минимизируя риски утечки и злоупотребления токенами.