Как вы обеспечиваете безопасность своих веб-приложений? Вы используете файлы cookie сеанса? Сторонняя аутентификация? SAML? Сегодня я собираюсь познакомить вас с изящным стандартом под названием JSON Web Tokens, или для краткости JWT. Если вы работали над веб-приложениями, есть большая вероятность, что вы хотя бы слышали о них, но сегодня я попытаюсь демистифицировать их для вас.
Если вы хотите вникнуть во все мельчайшие подробности, вы можете прочитать RFC, но это не цель данной статьи. Вместо этого я собираюсь:
- Дайте вам общий обзор того, что такое JWT
- Узнайте подробнее, как работает JWT и почему он хорош.
- Прикрыть некоторые распространенные ошибки безопасности
Что такое JWT?
JSON Web Token (JWT) - это открытый стандарт для создания и передачи данных. Он обеспечивает способ криптографической подписи полезной нагрузки JSON для проверки ее подлинности и целостности и / или шифрования полезной нагрузки JSON для обеспечения конфиденциальности. Обратите внимание, что иногда вы можете услышать криптографические подписи, называемые цифровыми подписями - это два названия одного и того же.
JWT - это токен с криптографической подписью
В этой статье мы будем обсуждать токены с криптографической подписью. Криптографически подписанные токены выдаются сервером пользователю, а затем могут быть представлены пользователем обратно на сервер, чтобы доказать, что пользователь авторизован для выполнения действия. У этой криптографической подписи есть два основных преимущества:
- Поскольку секретный ключ известен только серверу, только сервер может выдавать действительные токены.
- Невозможно изменить или подделать токен и его полезную нагрузку JSON без обнаружения из-за свойств криптографических подписей. (Хотите узнать, как это работает? Подробнее об этом здесь.)
Эти свойства делают JWT отличным механизмом для авторизации: когда пользователь входит в систему со своим именем пользователя и паролем, вы можете выдать ему токен, который содержит идентифицирующую информацию, такую как их идентификатор пользователя, их уровень разрешения / доступа и другие атрибуты, которые могут быть полезны. .
Затем, когда пользователь пытается получить доступ к маршрутам или функциям приложения, он представляет этот токен серверу, и сервер может считывать эти свойства из токена. Как только приложение убедится, что токен действителен (токены можно настроить на истечение срока действия) и что он не был подделан, вы можете принимать решения об авторизации на основе информации в токене.
Структура токена: 3 части JWT
Подписанный веб-токен JSON состоит из трех основных частей: заголовка, полезной нагрузки JSON и подписи.
- Заголовок содержит JSON, определяющий алгоритм шифрования, используемый для генерации криптографической подписи, а также может содержать другую информацию, такую как тип токена и информацию о цепочке сертификатов x.509, если вы ее используете.
- Полезная нагрузка, о которой мы уже говорили, представляет собой объект JSON. Содержащиеся в нем данные известны как утверждения. Стандарт JWT определяет семь стандартных требований. Вы можете думать об этом как о зарезервированных утверждениях точно так же, как некоторые ключевые слова в большинстве языков программирования зарезервированы для обозначения определенных вещей и не могут использоваться для других имен переменных (на ум приходят примеры
class
,if
,else
, и так далее). Эти стандартные утверждения могут хранить информацию об идентичности пользователя, сроке действия, эмитенте и т. Д. Вы также можете по желанию добавить к токену дополнительные утверждения. Я расскажу об этом подробнее в подразделе ниже. - Подпись, которая вычисляется путем кодирования заголовка и полезной нагрузки с помощью 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.