Cookie или localStorage?

Распространенная реализация авторизации в SPA выглядит так:
axios.post('auth', authData)
    .then(res => {
        token = res.data;
    });

localStorage.setItem('token', token);

axios.defaults.headers.common['token'] = token;

Во всяком случае во многих туториалах она выглядит примерно так.
Вчера смотрел курс Ильи Кантора по авторизации в WebSocket, где он рассматривал передачу session_id на сервер через вебсокеты. Авторизация в проекте была сделана на куках и стояла задача передать sid из куки в ws соединение.
Первый возможный вариант, на который указал Кантор - это убрать с кук флаг httpOnly и получить к ним доступ из js.
Но тут же оговорился, что так небезопасно делать, из-за xss.
Но ведь sid в localStorage это то же самое, что и sid в куках без httpOnly. Я имею ввиду доступность этих данных.
Так можно ли делать авторизацию способом из туториалов с сохранением sid в localStorage?
  • Вопрос задан
  • 5025 просмотров
Пригласить эксперта
Ответы на вопрос 4
@artinnok
бекенд-программист
Тут нет оптимального варианта - надо смотреть на бэкэнд и фронтенд совокупно.
Далее, считаем что фронтенд SPA, бэкэнд чистое API.

Если выбор за Cookies:
  1. На сервере необходимо реализовать защиту от CSRF
  2. На фронте также надо будет реализовать обвязку под передачу CSRF-токена
  3. Вся авторизация будет обрабатываться бэкэндом - т.е. он ставит куку через Set-Cookie с httpOnly и secure и сам же читает из куки для аутентификации / авторизации
  4. Фронтенд не имеет доступа к кукам - не думает об авторизации и об XSS
  5. Обычно, XSS используют чтобы украсть авторизационный токен через JS - если авторизационная кука httpOnly - нет доступа к кукам через JS, нет проблем

Если выбор за localStorage:
  1. Не надо делать CSRF защиту на сервере - нет кук, нет проблем
  2. Экранировать потенциально опасные данные бэкэндом на входе - обеспечит дополнительную защиту от XSS при рендере данных
  3. Надо делать защиту от XSS на фронте, т.е. экранирование данных при рендере - чтобы потенциально вредоносный JS код превращался в строку, а не вставлялся в DOM
  4. На фронте надо сделать обвязку под сохранение / передачу / валидацию токена
  5. Всегда остается человеческий фактор - забыли сделать экранирование при рендере на фронте, JS код имеет доступ к токену и он утек


Могу посоветовать использовать фреймворки, как на бэкэ, так и на фронте - они обычно имеют уже реализованную защиту от основных типов атак. Мы на проекте юзаем localStorage и React, ну и верим в лучшее :)
Ответ написан
Stalker_RED
@Stalker_RED
Храните где хотите.

Если передача данных идет по http, и сервер должен как-то отличать одного пользователя от другого (аутентификация нужна), то придется передавать хоть какой-то идентификатор. В url, в каком-то поле post-запроса, или в куках.
Обычно все делают в куках, это удобнее.

Если передача данных не http-запросами, то можете использовать какой-то другой способ аутентификации.
Ответ написан
alex-1917
@alex-1917
Если ответ помог, отметь решением
SowingSadness
@SowingSadness
web-разработчик
Делаем запрос на специальный URL в которой указан csrf токен, получаем токен для разового коннекта по websocket.
Формируем url для websocket с этим токеном в пути и подключаемся.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы