Локальное хранилище против файлов cookie

Я хочу сократить время загрузки моих сайтов, переместив все файлы cookie в локальное хранилище, поскольку они, похоже, имеют одинаковую функциональность. Есть ли плюсы / минусы (особенно в плане производительности) в использовании локального хранилища для замены функциональности cookie, кроме очевидных проблем совместимости?

9 ответов

Решение

Файлы cookie и локальное хранилище служат различным целям. Файлы cookie предназначены главным образом для чтения на стороне сервера, локальное хранилище может быть прочитано только на стороне клиента. Таким образом, вопрос в вашем приложении, кому нужны эти данные - клиент или сервер?

Если это ваш клиент (ваш JavaScript), то обязательно переключайтесь. Вы теряете пропускную способность, отправляя все данные в каждом заголовке HTTP.

Если это ваш сервер, локальное хранилище не так полезно, потому что вам нужно каким-то образом пересылать данные (с Ajax или скрытыми полями формы или чем-то еще). Это может быть хорошо, если серверу требуется только небольшое подмножество общих данных для каждого запроса.

Вы все равно захотите оставить свой сессионный cookie как cookie.

Согласно техническому различию, а также моему пониманию:

  1. Помимо старого способа сохранения данных, Cookies дают вам ограничение в 4096 байт (на самом деле 4095) - его на cookie. Локальное хранилище размером 5 МБ на домен - так что вопрос также упоминает

  2. localStorage является реализацией Storage Интерфейс. Он хранит данные без даты истечения срока их действия и очищается только с помощью JavaScript или очистки кэша браузера / локально сохраненных данных - в отличие от срока действия файлов cookie.

В контексте JWT Stormpath написал довольно полезную статью, в которой изложены возможные способы их хранения и (не) преимущества, относящиеся к каждому методу.

В нем также содержится краткий обзор атак XSS и CSRF и способов борьбы с ними.

Я приложил несколько коротких фрагментов статьи ниже, на случай, если их статья будет переведена в автономный режим или их сайт отключится.

Локальное хранилище

Проблемы:

Веб-хранилище (localStorage / sessionStorage) доступно через JavaScript в том же домене. Это означает, что любой JavaScript, работающий на вашем сайте, будет иметь доступ к веб-хранилищу, и из-за этого может быть уязвим к атакам межсайтового скриптинга (XSS). Короче говоря, XSS - это тип уязвимости, когда злоумышленник может внедрить JavaScript, который будет работать на вашей странице. Базовые XSS-атаки пытаются внедрить JavaScript через ввод данных, где злоумышленник ставит предупреждение ("Вы взломаны"); в форму, чтобы увидеть, если он запускается браузером и может быть просмотрен другими пользователями.

Предупреждение:

Чтобы предотвратить XSS, общим ответом является экранирование и кодирование всех ненадежных данных. Но это далеко не полная история. В 2015 году современные веб-приложения используют JavaScript, размещенный на CDN или вне инфраструктуры. Современные веб-приложения включают сторонние библиотеки JavaScript для A/B-тестирования, анализа воронки / рынка и рекламы. Мы используем менеджеры пакетов, такие как Bower, чтобы импортировать чужой код в наши приложения.

Что если скомпрометирован только один из используемых вами сценариев? На страницу может быть встроен вредоносный JavaScript, и веб-хранилище будет взломано. Эти типы атак XSS могут получить все веб-хранилища, которые посещают ваш сайт, без их ведома. Вероятно, поэтому многие организации советуют не хранить ничего ценного или доверять какой-либо информации в веб-хранилище. Это включает в себя идентификаторы сеанса и токены.

В качестве механизма хранения Web Storage не применяет никаких безопасных стандартов во время передачи. Любой, кто читает и использует веб-хранилище, должен проявить должную осмотрительность, чтобы всегда отправлять JWT по HTTPS, а не по HTTP.

Печенье

Проблемы:

Файлы cookie, используемые с флагом cookie HttpOnly, недоступны через JavaScript и защищены от XSS. Вы также можете установить флажок Безопасный файл cookie, чтобы гарантировать, что файл cookie отправляется только через HTTPS. Это одна из главных причин того, что в прошлом cookie-файлы использовались для хранения токенов или данных сеанса. Современные разработчики не решаются использовать куки, потому что они традиционно требовали сохранения состояния на сервере, тем самым нарушая лучшие практики RESTful. Файлы cookie как механизм хранения не требуют сохранения состояния на сервере, если вы сохраняете JWT в файле cookie. Это потому, что JWT инкапсулирует все, что нужно серверу для обслуживания запроса.

Однако файлы cookie уязвимы для атак другого типа: подделка межсайтовых запросов (CSRF). CSRF-атака - это тип атаки, которая происходит, когда вредоносный веб-сайт, электронная почта или блог заставляет веб-браузер пользователя выполнять нежелательные действия на доверенном сайте, на котором пользователь в настоящий момент проходит проверку подлинности. Это эксплойт того, как браузер обрабатывает куки. Файл cookie может быть отправлен только на те домены, на которых он разрешен. По умолчанию это домен, который изначально установил cookie. Файл cookie будет отправлен для запроса независимо от того, находитесь ли вы на сайте galaxies.com или hahagonnahackyou.com.

Предупреждение:

CSRF можно предотвратить с помощью синхронизированных шаблонов токенов. Это звучит сложно, но все современные веб-фреймворки поддерживают это.

Например, у AngularJS есть решение для проверки того, что файл cookie доступен только вашему домену. Прямо из документов AngularJS:

При выполнении запросов XHR служба $http считывает токен из файла cookie (по умолчанию XSRF-TOKEN) и устанавливает его как заголовок HTTP (X-XSRF-TOKEN). Так как только cookie, который работает в вашем домене, может читать cookie, ваш сервер может быть уверен, что XHR пришел из JavaScript, работающего в вашем домене. Вы можете сделать эту защиту CSRF без сохранения состояния, включив xsrfToken Заявление JWT:

{
  "iss": "http://galaxies.com",
  "exp": 1300819380,
  "scopes": ["explorer", "solar-harvester", "seller"],
  "sub": "tom@andromeda.com",
  "xsrfToken": "d9b9714c-7ac0-42e0-8696-2dae95dbc33e"
}

Использование CSRF-защиты вашего веб-фреймворка делает файлы cookie надежными для хранения JWT. CSRF также можно частично предотвратить, проверив HTTP Referer и заголовок Origin в вашем API. Атаки CSRF будут иметь заголовки Referer и Origin, которые не связаны с вашим приложением.

Полный текст статьи можно найти здесь: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/

У них также есть полезная статья о том, как наилучшим образом спроектировать и внедрить JWT в отношении структуры самого токена: https://stormpath.com/blog/jwt-the-right-way/

С localStorageВеб-приложения могут хранить данные локально в браузере пользователя. До HTML5 данные приложения должны были храниться в файлах cookie, включенных в каждый запрос к серверу. localStorage является более безопасным, и большие объемы данных могут храниться локально, не влияя на производительность веб-сайта. Хотя localStorage является более современным, есть некоторые плюсы и минусы для обоих методов.

Печенье

Pros

  • Устаревшая поддержка (это было всегда)
  • Постоянные данные
  • Срок годности

Cons

  • Каждый домен хранит все свои куки в одной строке, что может затруднить анализ данных
  • Данные не зашифрованы, что становится проблемой, потому что...... хотя они и имеют небольшой размер, cookie-файлы отправляются с каждым HTTP-запросом Ограниченный размер (4 КБ)
  • SQL-инъекция может быть выполнена из cookie

Локальное хранилище

Pros

  • Поддержка большинством современных браузеров
  • Постоянные данные, которые хранятся прямо в браузере
  • Правила того же происхождения применяются к локальным данным хранения
  • Не отправляется с каждым HTTP-запросом
  • ~5 МБ хранилища на домен (это 5120 КБ)

Cons

  • Раньше ничего не поддерживали: IE 8, Firefox 3.5, Safari 4, Chrome 4, Opera 10.5, iOS 2.0, Android 2.0
  • Если серверу нужна сохраненная информация о клиенте, вы намеренно должны отправить ее.

localStorage использование почти идентично сеансу. У них довольно точные методы, поэтому переключение с сессии на localStorage это действительно детская игра. Однако, если сохраненные данные действительно важны для вашего приложения, вы, вероятно, будете использовать куки в качестве резервной копии на случай, если localStorage не доступен. Если вы хотите проверить поддержку браузера для localStorageвсе, что вам нужно сделать, это запустить этот простой скрипт:

/* 
* function body that test if storage is available
* returns true if localStorage is available and false if it's not
*/
function lsTest(){
    var test = 'test';
    try {
        localStorage.setItem(test, test);
        localStorage.removeItem(test);
        return true;
    } catch(e) {
        return false;
    }
}

/* 
* execute Test and run our custom script 
*/
if(lsTest()) {
    // window.sessionStorage.setItem(name, 1); // session and storage methods are very similar
    window.localStorage.setItem(name, 1);
    console.log('localStorage where used'); // log
} else {
    document.cookie="name=1; expires=Mon, 28 Mar 2016 12:00:00 UTC";
    console.log('Cookie where used'); // log
}

"Значения localStorage на защищенных (SSL) страницах изолированы", так как кто-то заметил, имейте в виду, что localStorage будет недоступен, если вы переключитесь с защищенного протокола "http" на "https", где файл cookie все еще будет доступен. Это очень важно знать, если вы работаете с защищенными протоколами.

Файлы cookie:

  1. Представлен до HTML5.
  2. Имеет срок годности.
  3. Очистить с помощью JS или Очистить данные просмотра браузера или по истечении срока действия.
  4. Будет отправлено на сервер по каждому запросу.
  5. Емкость 4 КБ.
  6. В файлах cookie могут храниться только строки.
  7. Есть два типа файлов cookie: постоянные и сеансовые.

Локальное хранилище:

  1. Представлено в HTML5.
  2. Не имеет срока годности.
  3. Очистить с помощью JS или Очистить данные просмотра браузера.
  4. Вы можете выбрать, когда данные должны быть отправлены на сервер.
  5. Емкость составляет 5 МБ.
  6. Данные хранятся неограниченное время и должны быть строкой.
  7. Есть только один тип.

Ключевые отличия:

Вместимость:

  • Локальное хранилище: 10 МБ
  • Файлы cookie: 4 КБ

Поддержка браузера:

  • Локальное хранилище: HTML5
  • Файлы cookie: HTML4, HTML5

Место хранения:

  • Локальное хранилище: только браузер
  • Файлы cookie: браузер и сервер

Отправить с запросом:

  • Локальное хранилище: Да
  • Файлы cookie: Нет

Доступ из:

  • Локальное хранилище: любое окно
  • Файлы cookie: любое окно.

Дата истечения срока:

  • Локальное хранилище: никогда не истекает, пока не будет выполнено с помощью javascript.
  • Файлы cookie: да, имеют срок годности.

Примечание: используйте то, что вам подходит.

Стоит также отметить, что localStorage не может использоваться, когда пользователи работают в "приватном" режиме в некоторых версиях мобильного Safari.

Цитируется из MDN ( https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage):

Примечание. Начиная с iOS 5.1, Safari Mobile хранит данные localStorage в папке кэша, которая может периодически очищаться по указанию ОС, как правило, если места недостаточно. Режим приватного просмотра в Safari Mobile также полностью запрещает запись в localStorage.

Куки:

  • доступен с помощью JavaScript , поэтому данные Cookie могут быть украдены с помощью атаки XSS(атака с использованием межсайтовых сценариев) , но установка флага HttpOnly в Cookie предотвращает доступ с помощью JavaScript , поэтому данные Cookie защищены от атаки XSS .

  • уязвим для CSRF(подделка межсайтовых запросов) , но установка флага SameSite с Lax на Cookie смягчает CSRF , а установка флага SameSite со Strict на Cookie предотвращает CSRF.

  • должен иметь дату истечения срока действия , поэтому, когда срок действия истекает , Cookie автоматически удаляется, поэтому, даже если вы забыли удалить Cookie , Cookie автоматически удаляется из-за даты истечения срока действия .

  • составляет около 4 КБ как общий размер (в зависимости от браузеров).

Локальное хранилище:

  • доступен с помощью JavaScript , поэтому данные локального хранилища могут быть украдены с помощью атаки XSS(атака межсайтовых сценариев) , тогда, как я исследовал, не существует простых средств защиты локального хранилища от атаки XSS .

  • не уязвим для CSRF(подделка межсайтовых запросов) .

  • не имеет даты истечения срока действия , поэтому, если вы забыли удалить данные локального хранилища , данные локального хранилища могут остаться навсегда.

  • составляет около 5 МБ как общий размер (в зависимости от браузеров).

Я рекомендую использовать Cookie для конфиденциальных данных и Local Storage для неконфиденциальных данных .

Локальное хранилище может хранить до 10 МБ автономных данных, тогда как сеанс может хранить до 5 МБ данных. Но куки могут хранить только 4 КБ данных в текстовом формате.

Что ж, скорость локального хранилища в значительной степени зависит от браузера, который использует клиент, а также от операционной системы. Chrome или Safari на Mac могут быть намного быстрее, чем Firefox на ПК, особенно с новыми API. Как всегда, тестирование - ваш друг (я не смог найти никаких ориентиров).

Я действительно не вижу огромной разницы в cookie и локальном хранилище. Кроме того, вам следует больше беспокоиться о проблемах совместимости: не все браузеры даже начали поддерживать новые API-интерфейсы HTML5, поэтому файлы cookie будут лучшим выбором для скорости и совместимости.

Другие вопросы по тегам