Сравнение ключей API с авторизацией JWT: подробный обзор
30 марта 2022 г.Когда вы создаете свои собственные API, вам нужно будет изучить свои варианты использования , чтобы определить, какой метод безопасности следует реализовать для каждого API.
Для некоторых случаев использования ключей API достаточно; в других вам понадобится дополнительная защита и гибкость, которые обеспечиваются авторизацией JSON Web Tokens (JWT). Таким образом, в сравнении ключей API и авторизации JWT победителем оказывается... как повезет.
Все вызовы API требуют определенной меры безопасности и контроля доступа.
Ключи API с разумным ACL могут обеспечить достаточную безопасность, не добавляя слишком много накладных расходов. Но с ростом использования микросервисов практически для каждой маленькой и большой задачи вашей экосистеме API может потребоваться более унифицированный, детальный и безопасный метод, такой как авторизация JWT.
Когда ключи API в порядке
Интернет-компании, использующие облачный поисковый API, обычно могут предоставлять ключи API только для чтения без большого риска, если базовый индекс данных не содержит секретов.
На самом деле, клиентские приложения должны подключаться к облачной поисковой системе напрямую из соображений производительности, раскрывая таким образом свой ключ API, чтобы избежать более длительного перехода к внутреннему серверу перед переходом в облако. С другой стороны, обновления индекса требуют ограниченного доступа к ключам API, которые ни в коем случае нельзя раскрывать.
Но в обоих случаях использования (поиск и индексирование) ключи API обычно подходят; нет острой необходимости в накладных расходах на авторизацию JWT.
Когда пора задуматься об авторизации JWT
Однако API все чаще требуют большей гибкости и защиты.
Авторизация JWT не только добавляет дополнительный уровень безопасности (подробнее об этом ниже), но также предоставляет более управляемый и простой метод управления множеством и сетью API, используемых ежедневно. Как описано в следующих разделах:
JWT централизует аутентификацию и авторизацию, создавая один общий токен , который содержит информацию о пользователе и уровне приложения (зашифрованную или хешированную), чтобы помочь любому API в Одна и та же экосистема определяет, что разрешено делать держателю токена.
Ключи API, на первый взгляд, кажутся такими простыми — вам просто нужно отправить правильный ключ API, и вы готовы к работе. Но это немного обманчиво.
Когда ваша экосистема опирается на множество интегрированных микросервисов, управление многочисленными ключами API становится запутанным, ненадежным и практически невозможным.
Их количество растет, они меняются, срок их действия истекает, они удаляются, меняются их ACL — все это и многое другое без уведомления приложений и пользователей, полагающихся на те же ключи API.
Благодаря JWT вы закладываете основу для архитектуры единого входа. Мы обсудим это ниже в разделе Переход на JWT.
Использование ключей API против. Авторизация JWT
Использование ключей API
Ключи API являются прямыми, простыми и полностью прозрачными. Они не представляют никакой базовой информации, они не шифруют секретное сообщение. Они просто нечитаемый уникальный идентификатор.
Вот пример общедоступного ключа API в javascript на стороне клиента. Код включает идентификатор приложения (app-id-BBRSSHR
), который использует ключ API (temp-search-key-ere452sdaz56qsjh565d
), чтобы разрешить поиск.
Идентификатор приложения относится к одному из ваших пользовательских приложений (например, веб-сайту или службе потоковой передачи). Ключ API является временным и недолговечным (срок действия которого истекает через определенный период времени), чтобы обеспечить некоторую защиту от нежелательного использования или злоупотребления.
```javascript
импортировать { hitTemplate } из "./helpers";
постоянный поиск = мгновенный поиск({
appId: "идентификатор приложения-BBRSSHR",
apiKey: "temp-search-key-ere452sdaz56qsjh565d",
indexName: "demo_ecommerce"
Другой пример: индексирование, для которого требуется более безопасный ключ API. Он имеет тот же формат (appId
+ apiKey
), но является закрытым, поскольку скрыт от общественности либо в скомпилированном коде, либо в защищенной базе данных на вашем сервере.
Идентификатор приложения («YourApplicationID») относится к системе бэк-офиса. Ключ API («YourAdminAPIKey») может быть постоянным ключом администратора, который меняется только один раз в год для упрощения обслуживания.
```php
используйте Algolia\AlgoliaSearch\SearchClient;
$клиент = SearchClient::создать(
'Идентификатор вашего приложения',
'Ваш АдминAPIKey'
$index = $client->initIndex('demo_ecommerce');
$индекс->сохранитьОбъект(
'firstname' => 'Джимми',
'lastname' => 'Барнингер',
'город' => 'Нью-Йорк',
'objectID' => 'мойID'
Используя токен JWT
Токен JWT – это большой нечитаемый набор символов, который содержит скрытую и закодированную информацию, замаскированную подписью или алгоритмом шифрования. Он состоит из трех частей: заголовка, тела и подписи. Они разделены точкой: Header.Body.Signature
.
```json
EZPZAAdsqfqfzeezarEUARLEA.sqfdqsTIYfddhtreujhgGSFJ.fkdlsqEgfdsgkerGAFSLEvdslmgIegeVDEzefsqd
Заголовок JWT – EZPZAAdsqfqfzeezarEUARLEA
, который содержит следующую информацию:
```json
"алг": "HS256",
"тип": "JWT"
"суб": "1234567890",
"имя": "Джон Доу",
"иат": 1516239022
Доступны различные алгоритмы, например, RS256 и HS256. Здесь мы используем HS256, который требует использования закрытого ключа при создании подписи. RS256
использует комбинацию закрытого и открытого ключа.
Тело JWT (называемое полезной нагрузкой) — это sqfdqsTIYfddhtreujhgGSFJ
, которое содержит идентификатор пользователя, помогающий установить права пользователя токена. Он также предоставляет другую информацию, например дату истечения срока действия (чем короче, тем безопаснее):
```json
"суб": "1234567890",
"имя": "Джон Доу",
"иат": 1516239022
Подпись – fkdlsqEgfdsgkerGAFSLEvdslmgIegeVDEzefsqd
, которая создается путем объединения заголовка, тела и общего закрытого ключа с использованием метода хеширования HS256, как указано в заголовке.
```php
HMACSHA256(
base64UrlEncode (заголовок) + "." +
base64UrlEncode (полезная нагрузка),
секрет)
Вот как вы получаете следующий токен: Header.Body.Signature
:
EZPZAAdsqfqfzeezarEUARLEA.sqfdqsTIYfddhtreujhgGSFJ.fkdlsqEgfdsgkerGAFSLEvdslmgIegeVDEzefsqd
Несколько слов об аутентификации и авторизации
И ключ API, и JWT используются для аутентификации и авторизации, но они делают это по-разному.
- Аутентификация позволяет пользователю или приложению использовать один или несколько методов API.
- Авторизация определяет, как они могут использовать эти методы. Некоторые приложения или пользователи могут только читать данные; другие могут обновляться; другие являются администраторами (роли и разрешения). То же самое касается ключей API, поскольку они управляются их ACLS — они могут быть только для чтения, с доступом для записи или с правами администратора.
Ключи API аутентифицируют и авторизуют с использованием одного и того же ключа API. Для авторизации JWT требуется начальный процесс аутентификации, прежде чем он сгенерирует токен авторизации.
После создания токена он используется во всей экосистеме, чтобы определить, что может и что не может делать владелец токена.
Кроме того, ключи API аутентифицируют приложение*,* а не пользователя; тогда как JWT аутентифицирует и пользователя, и приложение. Конечно, вы можете использовать API-ключи для авторизации на уровне пользователя, но это не очень хорошо для этого разработано — экосистеме потребуется генерировать и управлять API-ключами для каждого пользователя или идентификатора сеанса, что излишне обременительно для системы.
Несколько слов о лучшей защите и безопасности
С точки зрения безопасности, как ключи API, так и JWT открыты для атак. Наилучшей мерой безопасности является внедрение безопасной архитектуры для всех сквозных коммуникаций.
Тем не менее, ключи API исторически менее безопасны, потому что они полагаются скрытыми.
Вы можете скрыть ключи с помощью SSL/TLS/HTTPS или ограничить их использование внутренними процессами. Однако вы не можете контролировать все использование API; Ключи API могут утечь; HTTPS не всегда возможен; и так далее.
Благодаря JWT, поскольку токен хешируется/зашифровывается, он использует более безопасную методологию, которая с меньшей вероятностью будет раскрыта.
Какая информация содержится в токене JWT?
Наиболее заметное различие между ключом API и токеном JWT * заключается в том, что токены JWT автономны: они содержат информацию, необходимую API для защиты транзакции, и определяют степень детализации прав владельца токена.
Напротив, ключи API используют свою уникальность для получения начального доступа; но затем API должен найти связанный с ключом ACL в центральной таблице, чтобы точно определить, к чему этот ключ дает доступ.
Как правило, ключ API обеспечивает безопасность только на уровне приложения, предоставляя каждому пользователю одинаковый доступ; тогда как токен JWT обеспечивает доступ на уровне пользователя.
Токен JWT может содержать такую информацию, как дата истечения срока действия и идентификатор пользователя для определения прав пользователя во всей экосистеме.
Давайте взглянем на некоторую информацию, которую вы можете включить в токен JWT:
iss (эмитент): определяет принципала, выпустившего JWT.
sub (субъект): определяет принципала, который является субъектом JWT. Должно быть уникальным
aud (аудитория): определяет получателей, для которых предназначен JWT (массив строк/uri)
exp (время истечения срока действия): определяет время истечения срока действия (UTC Unix), после которого вы больше не должны принимать этот токен. Это должно быть после выданного времени.
nbf (не раньше): определяет время UTC Unix, до которого нельзя принимать JWT.
iat (выпущено в): определяет время UTC Unix, в которое был выпущен JWT.
jti (идентификатор JWT): предоставляет уникальный идентификатор для JWT.
Пример:
```json
"исс": "переполнение стека",
"суб": "Джо",
"ауд": ["все"],
"иат": 1300819370,
"эксп": 1300819380,
"jti": "3F2504E0-4F89-11D3-9A0C-0305E82C3301",
"контекст":
"Пользователь":
"ключ": "Джо",
"displayName": "Джо Смит"
"роли":["администратор","конечный пользователь"]
Авторизация JWT обеспечивает гибкость, надежность и безопасность
Итак, вот сценарий. У вас много приложений:
- Приложения, которые позволяют нам отслеживать использование API всеми нашими пользователями.
- Приложения, предоставляющие доступ к платежным данным и данным клиентов.
- Приложения, которые позволяют пользователям API изменять настройки в разных системах.
- Приложения, которые извлекают данные о продуктах или бизнес-контент.
- И так далее.
Делаем это с помощью ключей API
Проблема возникает, когда шоу запущено большим количеством API. Где вы храните более 100 ключей API, необходимых для всего этого доступа? Для управления слишком большим количеством ключей API требуется, чтобы таблица ключей API была доступна для всех приложений, работающих в экосистеме.
Таким образом, каждое приложение в экосистеме должно знать о базе данных. Каждое приложение должно будет подключаться и читать из этой таблицы. И некоторым приложениям будет разрешено генерировать новые ключи или изменять существующие ключи.
Все это хорошо, но становится трудно поддерживать. Один из способов справиться с этим — создать API, который проверяет ключ в этой базе данных. Но для этого вам понадобится вторая система аутентификации для подключения к этому API.
Мало того, что извлечение ключей API утомительно, так еще и поддержание их продолжительности и уровня авторизации становится утомительным. И не каждое приложение работает на уровне приложения, им нужны права на уровне пользователя.
Кроме того, API можно использовать по-разному в разных системах. Хуже того, разные приложения используют общие ключи API и, следовательно, зависят от разных приложений для поддержания правильных уровней доступа к общим ключам API.
Переход на JWT
Любой API, требующий аутентификации, может легко переключиться на авторизацию JWT. С авторизацией JWT вы получаете аутентификацию на основе пользователя. После аутентификации пользователя он получает безопасный токен, который может использовать во всех системах.
Управление пользователем (и, следовательно, токеном) централизовано. Вы устанавливаете права доступа и даете каждому пользователю разные права для каждой системы. Конечная точка авторизации JWT аутентифицирует пользователя и создает токен.
При такой архитектуре следующим шагом будет создание единого входа в полную экосистему и использование только токена для получения прав.
В конце концов, самый простой, надежный и управляемый подход — создать эту единую конечную точку, предназначенную для выполнения как аутентификации, так и авторизации, чтобы все остальные серверы во всей экосистеме могли полагаться на эту центральную точку для авторизации взаимодействия API между клиентом и сервером. .
В общем, иногда JWT абсолютно необходим, а иногда это излишество
Как разработчик приложений, я в первую очередь беспокоюсь при создании API-интерфейсов, чтобы они использовались правильно и предоставляли правильные данные и функциональные возможности.
Поэтому я в значительной степени полагаюсь на советы DevOps, чтобы предложить лучшую и наиболее управляемую безопасность. Но дело не только в безопасности.
В большой экосистеме нам нужен простой и надежный способ доступа к микросервисам в нескольких системах и серверах, который лучше всего подходит для централизации процессов аутентификации и авторизации.
JWT является излишним в следующих двух ситуациях:
- Простая экосистема с несколькими API.
- Поставщики сторонних API.
Сторонние API должны быть простыми в использовании и быстрыми в реализации, с небольшой предварительной работой при интеграции.
Кроме того, вам необходимо поделиться ключом, используемым для подписи токена. Так что лучше всего, когда вы контролируете оба конца, что маловероятно в сторонних декорациях. Вы также должны доверять реализации. например, API может игнорировать дату истечения срока действия или NBF («не раньше»).
JWT не перегружен, когда…
Вы захотите использовать JWT, когда нескольким службам необходимо взаимодействовать друг с другом по обширной сети.
Централизация и защита этих обменов имеет решающее значение. Это особенно важно, когда каждой сети или приложению требуются разные уровни доступа в зависимости от пользователя, а не только приложения.
Также важно иметь контроль над трафиком и иметь возможность расставлять приоритеты для сетевых вызовов. Наконец, вам нужен простой интерфейс plug-and-play при добавлении новых микросервисов или улучшении существующих.
- Впервые опубликовано здесь.*
Автор: Жюльен Бурдо, старший инженер-программист в Algolia, GitHub, Twitter, LinkedIn
Оригинал