Где разместить ключ API: пользовательский заголовок HTTP против заголовка авторизации с пользовательской схемой

18

Я разрабатываю REST API, используя авторизацию / аутентификацию через ключ API.

Я попытался выяснить, что является лучшим местом для этого, и обнаружил, что многие люди предлагают использовать собственный заголовок HTTP ProjectName-Api-Key, например, например:

ProjectName-Api-Key: abcde

но также возможно и идеологически правильно использовать Authorizationзаголовок с пользовательской схемой, например:

Authorization: ApiKey abcde

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

Каким способом вы бы предпочли отправить ключ API?

RomanG
источник
Проекты под моим руководством используют Authorization: Bearer <token>заголовок, и с этим никогда не было проблем. Токены являются JWT s.
Энди
1
@DavidPacker Как я понимаю, Bearerсхема используется исключительно с oAuth2. Применение его отдельно от oAuth звучит как злоупотребление им. Почему правильно использовать эту схему, если нет oAuth? Кстати, у меня были проблемы с выбором типа авторизации для моего API. API будет доступен только для одной доверенной службы, поэтому я исследовал поток учетных данных клиента oAuth2 и не нашел никаких преимуществ по сравнению с ApiKey в моем случае.
RomanG
@DavidPacker Тогда я понял, что авторизацию ApiKey можно рассматривать как допустимую реализацию oAuth, если она ApiKeyбыла переименована и интерпретирована как Access Tokenпредоставленная клиенту без истечения срока действия. Это своего рода философский аспект, я решил не приводить сложных определений, если мой случай можно описать простыми словами, и решил просто назвать его «ApiKey». Если ваш протокол реализует стандарт oAuth, я могу согласиться на использование Bearer, но это не так, я думаю, что эту схему нельзя применить.
RomanG
2
Ты слишком ограничиваешь себя. Потребитель API может не заботиться о том, реализовали ли вы OAuth или нет. То, что их волнует, - это безопасность токенов, то, что выдача токенов работает и что они могут быть должным образом аутентифицированы. Они рекомендуют использовать Bearer прямо в документации JWT . JWT идеально подходит к схеме Bearer, и я не могу больше рекомендовать JWT. Они идеально подходят для приложений REST, потому что вы можете аутентифицировать пользователя, даже не обращаясь к базе данных - если вам не нужна функция отзыва токенов.
Энди
1
(проезжайте мимо) ... пожалуйста, позаботьтесь о том, чтобы ключи API были общими секретами, которые обычно передаются между настроенной проверяющей стороной и средством проверки подлинности, а не для передачи идентификатора или авторизации. Иными словами, они предназначены только для инициации рукопожатия безопасности, а не для представления результата аутентификации. Ключ API сообщает ваши полномочия идентифицировать себя по доверенному аутентификатору системы. Использование ключа в качестве токена для управления безопасным доступом к ресурсам - плохо, Джуджу
К. Алан Бейтс

Ответы:

13

Если вы используете авторизацию, будьте последовательны

Некоторые утверждают, что следующее не является необходимым ( и не так давно я бы с ними согласился ), но в наши дни, если мы используем Authorizationзаголовок, мы должны сообщить тип токена, потому что ключи API сами по себе не описательны. 1 .

Почему я считаю это необходимым и почему я считаю это важным? Потому что в настоящее время поддержка различных протоколов аутентификации / авторизации стала обязательной. Если мы планируем использовать Authorizationзаголовок для всех этих протоколов, мы должны сделать нашу аутентификацию согласованной. Способ сообщения о том, какой токен мы отправляем и какой протокол авторизации должен применяться, также должен быть указан в заголовке.

Authorization: Basic xxxx
Authorization: Digest xxxx
Authorization: Bearer xxxx
Authorization: ApiKey-v1 xxxx
Authorization: ApiKey-v2 xxxx

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

Обеспокоенность

Проблемы, с которыми я столкнулся при реализации своих собственных схем, были аналогичны тем, которые были прокомментированы.

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

Скажем клиенты , скажем библиотеки, фреймворки, обратные прокси .

преимущества

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

Так авторизация или пользовательский заголовок?

По моему опыту, реализация моей собственной Authorizationсхемы заняла у меня тот же объем работы (или больше), что и реализация пользовательских заголовков авторизации, с небольшой разницей в большей свободе проектирования и большем контроле над кешем, когда я использовал собственные заголовки. Причина довольно глупая, в большинстве случаев у меня Cache-controlустановлен параметр no-cacheили no-store, позволяющий мне делать вызовы на сервер более детерминированными (это важно, когда дело доходит до отслеживания и тестирования) независимо от топологии сети.


1: Я считаю, что этот ответ очень ясен в отношении ключей API

LAIV
источник
4
X-
Начиная с
1
опс! Я не знал Отредактировано и исправлено.
Laiv
До этого вопроса я думал, что большинство всех помещают ключ API в URL, но используют HTTPS, чтобы скрыть его. Приятно видеть некоторые альтернативы. Например, позволяет авторизации содержательной или pamameter запрос: contentful.com/developers/docs/references/content-delivery-api/...
user949300
1
@ user949300 ... использование зашифрованного общего секретного ключа (например, ключа API в URI поверх ssl), очевидно, более безопасно, чем вообще ничего, но легко подделывается, если оно перехвачено и не обеспечивает детализации идентификаторов. Я никогда не использовал api_keys для чего-либо, кроме обмена данными между компьютерами, где я сопоставляю общий секретный код доверяющих сторон и идентификаторы компьютеров из белого списка, которым разрешено работать с этим общим секретным ключом. После того, как машина подключена к машине, оператор-человек аутентифицируется с помощью других средств.
К. Алан Бейтс
@K. Алан Бейтс. Большинство моих взаимодействий с API было связано с относительно «неважными» вещами, такими как бесплатные уровни геокодирования, отчеты о погоде и т. Д., Где ключ API больше предназначен для ограничения скорости, чем для серьезных пользовательских секретов. Итак, что касается OP, зависит от того, какой уровень безопасности необходим.
user949300