Как вы обеспечиваете безопасность своих веб-приложений? Вы используете файлы cookie сеанса? Сторонняя аутентификация? SAML? Сегодня я собираюсь познакомить вас с изящным стандартом под названием JSON Web Tokens, или для краткости JWT. Если вы работали над веб-приложениями, есть большая вероятность, что вы хотя бы слышали о них, но сегодня я попытаюсь демистифицировать их для вас.

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

  1. Дайте вам общий обзор того, что такое JWT
  2. Узнайте подробнее, как работает JWT и почему он хорош.
  3. Прикрыть некоторые распространенные ошибки безопасности

Что такое JWT?

JSON Web Token (JWT) - это открытый стандарт для создания и передачи данных. Он обеспечивает способ криптографической подписи полезной нагрузки JSON для проверки ее подлинности и целостности и / или шифрования полезной нагрузки JSON для обеспечения конфиденциальности. Обратите внимание, что иногда вы можете услышать криптографические подписи, называемые цифровыми подписями - это два названия одного и того же.

JWT - это токен с криптографической подписью

В этой статье мы будем обсуждать токены с криптографической подписью. Криптографически подписанные токены выдаются сервером пользователю, а затем могут быть представлены пользователем обратно на сервер, чтобы доказать, что пользователь авторизован для выполнения действия. У этой криптографической подписи есть два основных преимущества:

  1. Поскольку секретный ключ известен только серверу, только сервер может выдавать действительные токены.
  2. Невозможно изменить или подделать токен и его полезную нагрузку JSON без обнаружения из-за свойств криптографических подписей. (Хотите узнать, как это работает? Подробнее об этом здесь.)

Эти свойства делают JWT отличным механизмом для авторизации: когда пользователь входит в систему со своим именем пользователя и паролем, вы можете выдать ему токен, который содержит идентифицирующую информацию, такую ​​как их идентификатор пользователя, их уровень разрешения / доступа и другие атрибуты, которые могут быть полезны. .

Затем, когда пользователь пытается получить доступ к маршрутам или функциям приложения, он представляет этот токен серверу, и сервер может считывать эти свойства из токена. Как только приложение убедится, что токен действителен (токены можно настроить на истечение срока действия) и что он не был подделан, вы можете принимать решения об авторизации на основе информации в токене.

Структура токена: 3 части JWT

Подписанный веб-токен JSON состоит из трех основных частей: заголовка, полезной нагрузки JSON и подписи.

  1. Заголовок содержит JSON, определяющий алгоритм шифрования, используемый для генерации криптографической подписи, а также может содержать другую информацию, такую ​​как тип токена и информацию о цепочке сертификатов x.509, если вы ее используете.
  2. Полезная нагрузка, о которой мы уже говорили, представляет собой объект JSON. Содержащиеся в нем данные известны как утверждения. Стандарт JWT определяет семь стандартных требований. Вы можете думать об этом как о зарезервированных утверждениях точно так же, как некоторые ключевые слова в большинстве языков программирования зарезервированы для обозначения определенных вещей и не могут использоваться для других имен переменных (на ум приходят примеры class, if, else, и так далее). Эти стандартные утверждения могут хранить информацию об идентичности пользователя, сроке действия, эмитенте и т. Д. Вы также можете по желанию добавить к токену дополнительные утверждения. Я расскажу об этом подробнее в подразделе ниже.
  3. Подпись, которая вычисляется путем кодирования заголовка и полезной нагрузки с помощью base64, объединения их вместе с ., а затем шифрования этой строки с помощью закрытого ключа сервера. Чтобы проверить токен, сервер повторит этот процесс для заголовка и полезной нагрузки полученного токена, а затем сравнит результат с блоком подписи токена. Если токен был подделан, они не будут совпадать.

Чтобы сформировать токен из этих частей, каждая часть закодирована в base64, и части соединяются вместе точками. Ниже приведен пример:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.gzSraSYS8EXBxLN_oWnFSRgCzcmJmMjLiuyu5CSpyHI

Заявления JWT - хранение информации в токенах JWT

Заявления JWT определены в полезной нагрузке токена. Они могут хранить полезную информацию о токене, эмитенте, пользователе, которому он был выдан, а также другую дополнительную информацию.

Например, когда пользователь входит в систему, сервер проверяет, есть ли у него права администратора, а затем выдает пользователю токен, содержащий его идентификатор пользователя, и сообщает, есть ли у него права администратора:

В этом случае identity - это GUID, который является идентификатором пользователя. Поля iat, nbf, exp иjti являются стандартными заявлениями. user_claims - это утверждение, которое я добавил для хранения дополнительной информации о пользователе.

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

Преимущества использования JWT в вашем приложении

Использование веб-токенов JSON имеет ряд преимуществ:

  • Интернет работает на JavaScript, поэтому JSON - отличный выбор для хранения информации аутентификации. Но JWT не ограничивается приложениями JavaScript - все, от PHP до Python и Go, может использовать JSON. Он гибкий и простой в использовании.
  • Заявления JWT позволяют легко хранить дополнительную информацию о пользователях, к которым вы можете получить доступ в своем приложении, не выполняя поиск в базе данных.
  • Токены небольшие и безопасны для URL-адресов. Они могут храниться как куки, в локальном хранилище или в хранилище сеансов.
  • В большинстве распространенных веб-фреймворков есть библиотеки для JWT, которые делают всю тяжелую работу за вас. (Я включу ссылки на некоторые из них внизу этой статьи).

Распространенные подводные камни JWT

Как и любой другой механизм безопасности, у JWT есть несколько распространенных ошибок. Их нетрудно избежать, но вам нужно знать, что они из себя представляют, чтобы их избежать:

Убедитесь, что ваш ключ в безопасности

Если вы следите за демонстрацией, у них обычно есть пример ключа с примером кода. Не копируйте их ключ - вместо этого создайте свой собственный. Не используйте короткие слова или фразы - это должен быть длинный случайный ключ.

Не вводите секретный ключ в свое приложение жестко

Чтобы подписывать токены, ваш сервер должен иметь секретный ключ, которым он пользуется. В зависимости от структуры JWT, которую вы используете для своего языка, вы можете указать это одним из нескольких способов. Важно не встраивать ключ в свое приложение жестко. Жесткое кодирование ключа приведет к тому, что ключ будет передан вашему контролю версий. (Это особенно плохо, если ваш проект является публичным!) Любой, у кого есть ключ, может создавать токены, поэтому важно держать это в секрете. Я рекомендую использовать переменные окружения или какой-нибудь менеджер секретов.

Хранить токены в файлах cookie? Делайте это осторожно.

Обязательно установите атрибуты secure и HttpOnly в ваших файлах cookie JWT. Атрибут secure гарантирует, что браузер отправляет токен только через зашифрованное (https) соединение, чтобы предотвратить перехват файла cookie.

Атрибут HttpOnly гарантирует, что к файлу cookie нельзя будет получить доступ через Javascript, что поможет смягчить атаки межсайтового скриптинга (XSS).

Более подробную информацию можно найти здесь.

Заключение

Ключевые выводы:

  • JWT - это открытый стандарт, который можно использовать для авторизации после аутентификации ваших пользователей.
  • Токены JWT нельзя подделать или изменить (без обнаружения) без знания секретного ключа.
  • JWT позволяет хранить данные JSON («утверждения») в токенах, которые можно использовать для авторизации или других целей.
  • JWT прост в использовании, и существует множество отличных фреймворков для его реализации в ваших приложениях.
  • Убедитесь, что ваше приложение безопасно управляет секретным ключом и токенами JWT.

Надеюсь, вы найдете это полезным! Дайте мне знать, что вы думаете, в комментариях ниже.

Сноска

Как и было обещано, вот несколько ссылок на библиотеки JWT для Python / Flask, Node.js / Express и PHP:

Flask-jwt-extended: очень надежный модуль для фреймворка Python Flask, который мне очень нравится использовать.

Express-jwt: отличный пакет, который легко интегрируется в приложения Node.js Express. Я очень рекомендую его, если вы работаете с Node.js и Express.

Php-jwt: высококачественная библиотека JWT для PHP, поддерживаемая Firebase.