Подтвердить что ты не робот

Где сохранить JWT в приложении на основе браузера и как его использовать

Я пытаюсь внедрить JWT в моей системе аутентификации, и у меня есть несколько вопросов. Чтобы сохранить токен, я мог бы использовать файлы cookie, но также можно использовать localStorage или sessionStorage.

Какой будет лучший выбор?

Я прочитал, что JWT защищает сайт от CSRF. Однако я не могу представить, как это будет работать, если я сохраню токен JWT в хранилище файлов cookie.

Как бы защитить его от CSRF?

Обновление 1
Я видел несколько примеров использования, например:

curl -v -X POST -H "Authorization: Basic VE01enNFem9FZG9NRERjVEJjbXRBcWJGdTBFYTpYUU9URExINlBBOHJvUHJfSktrTHhUSTNseGNh"

Как я могу реализовать это, когда я делаю запрос на сервер из браузера? Я также видел, что некоторые реализуют токен в URL-адресе:

http://exmple.com?jwt=token

Если бы я сделал запрос через AJAX, тогда я мог бы установить заголовок как jwt: [token], а затем я мог бы прочитать маркер из заголовка.

Обновление 2

Я установил расширение расширенного клиента REST Client Google Chrome и смог передать токен в качестве настраиваемого заголовка. Можно ли установить данные заголовка через Javascript при выполнении запроса GET на сервер?

4b9b3361

Ответ 1

Посмотрите на этот веб-сайт: https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/

Если вы хотите сохранить их, вы должны использовать localStorage или sessionStorage, если они доступны, или файлы cookie. Вы также должны использовать заголовок авторизации, но вместо базовой схемы используйте однонаправленный носитель:

curl -v -X POST -H "Authorization: Bearer YOUR_JWT_HERE"

С помощью JS вы можете использовать следующий код:

<script type='text/javascript'>
// define vars
var url = 'https://...';

// ajax call
$.ajax({
    url: url,
    dataType : 'jsonp',
    beforeSend : function(xhr) {
      // set header if JWT is set
      if ($window.sessionStorage.token) {
          xhr.setRequestHeader("Authorization", "Bearer " +  $window.sessionStorage.token);
      }

    },
    error : function() {
      // error handler
    },
    success: function(data) {
        // success handler
    }
});
</script>

Ответ 2

Выбор хранилища - это скорее компромисс, чем поиск окончательного наилучшего выбора. Давайте рассмотрим несколько вариантов:

Вариант 1 - Веб-хранилище (localStorage или sessionStorage)

Pros

  • Браузер не будет автоматически включать что-либо из веб-хранилища в HTTP-запросы, делая его не уязвимым для CSRF
  • Доступ к Javascript может быть доступен только в том же домене, который создал данные
  • Позволяет использовать наиболее семантически правильный подход для передачи учетных данных аутентификации маркера в HTTP (заголовок Authorization с помощью схемы Bearer)
  • Очень легко вишня выбрать запросы, которые должны содержать аутентификацию

Против

  • Невозможно получить доступ к Javascript, работающему в поддомене того, который создал данные (значение, написанное example.com, не может быть прочитано sub.example.com)
  • ⚠️ Является уязвимым для XSS
  • Чтобы выполнить аутентифицированные запросы, вы можете использовать API-интерфейс браузера/библиотеки, который позволяет вам настроить запрос (передать токен в заголовке Authorization)

Использование

Вы используете браузер localStorage или sessionStorage API для хранения и последующего извлечения токена при выполнении запросов.

localStorage.setItem('token', 'asY-x34SfYPk'); // write
console.log(localStorage.getItem('token')); // read

Вариант 2 - cookie только для HTTP

Pros

  • не уязвим для XSS
  • Браузер автоматически включает токен в любом запросе, который соответствует спецификации файла cookie (домен, путь и время жизни)
  • Файл cookie может быть создан в домене верхнего уровня и использован в запросах, выполняемых поддоменами

Против

  • ⚠️ Он уязвим для CSRF
  • Вам нужно знать и всегда учитывать возможное использование файлов cookie в поддоменах
  • Черри, собирающая запросы, которые должны включать cookie, выполнима, но messier
  • Вы можете (по-прежнему) поражать некоторые проблемы с небольшими различиями в том, как браузеры обрабатывают файлы cookie.
  • ⚠️ Если вы не будете осторожны, вы можете реализовать стратегию смягчения CSRF, уязвимую для XSS
  • Серверная сторона должна проверить cookie для аутентификации вместо более подходящего заголовка Authorization

Использование

Вам не нужно ничего делать на стороне клиента, так как браузер автоматически позаботится о вас.

Вариант 3 - Javascript доступный cookie игнорируется серверной стороной

Pros

  • не уязвим для CSRF (, потому что он игнорируется сервером)
  • Файл cookie может быть создан в домене верхнего уровня и использован в запросах, выполняемых поддоменами
  • Позволяет использовать наиболее семантически правильный подход для передачи учетных данных аутентификации маркера в HTTP (заголовок Authorization с помощью схемы Bearer)
  • Несколько легко вишня выбрать запросы, которые должны содержать аутентификацию

Против

  • ⚠️ Он уязвим для XSS
  • Если вы не обращаете внимания на путь, в котором вы устанавливаете cookie, cookie автоматически включается браузером в запросы, которые добавят лишние служебные данные
  • Чтобы выполнить аутентифицированные запросы, вы можете использовать API-интерфейс браузера/библиотеки, который позволяет вам настроить запрос (передать токен в заголовке Authorization)

Использование

Вы используете браузер document.cookie API для хранения и последующего извлечения маркера при выполнении запросов. Этот API не такой тонкий, как веб-хранилище (вы получаете все файлы cookie), поэтому вам нужна дополнительная работа для анализа необходимой информации.

document.cookie = "token=asY-x34SfYPk"; // write
console.log(document.cookie); // read

Дополнительные примечания

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


Заключение - окончательные примечания

Моя рекомендация для большинства распространенных сценариев будет заключаться в опции 1, главным образом потому, что:

  • Если вы создаете веб-приложение, вам нужно иметь дело с XSS; всегда, независимо от того, где вы храните свои жетоны
  • Если вы не используете аутентификацию на основе файлов cookie, CSRF не должен появляться даже на вашем радаре, поэтому вам нужно меньше беспокоиться о

Также обратите внимание, что параметры на основе файлов cookie также совершенно разные, поскольку куки 3-го варианта используются исключительно как механизм хранения, поэтому он почти так же, как если бы это была деталь реализации на стороне клиента. Однако Вариант 2 означает более традиционный способ проверки подлинности; для дальнейшего чтения этого файла cookie против токена вы можете найти эту статью интересной: Cookies vs Tokens: The Definitive Guide.

Наконец, ни один из вариантов не упоминает об этом, но использование HTTPS является обязательным, конечно, что означало бы, что файлы cookie должны быть созданы соответствующим образом, чтобы принять это во внимание.

Ответ 3

В этом сообщении в блоге есть превосходное боковое сравнение хранилища браузеров и файлов cookie и в каждом случае задействованы все потенциальные атаки. https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/

Более короткий ответ/спойлер: файлы cookie и добавить токен xsrf в jwt. Подробное объяснение в сообщении блога.