- PVSM.RU - https://www.pvsm.ru -

Вероятно, вы подумаете, что имея клиентскую библиотеку, можно реализовать OAuth для любого API буквально за десять минут. Или хотя бы за час.
Если вам это удастся, то, пожалуйста, сообщите об этом нам — мы угостим вас изысканным ужином и послушаем, как у вас это получилось.
Мы реализовали OAuth для пятидесяти самых популярных API, например, Google (Gmail, Calendar, Sheets и так далее), HubSpot, Shopify, Salesforce, Stripe, Jira, Slack, Microsoft (Azure, Outlook, OneDrive), LinkedIn, Facebook и для других OAuth API. [10]
Наш вывод: в реальном мире опыт работы с OAuth сравним с опытом работы с браузерными JavaScript API в 2008 году. Существует общий консенсус о различных аспектах, но в реальности у каждого API есть собственная интерпретация стандарта, особенности реализации, нестандартные поведения и расширения. В результате за каждым углом вас ожидают выстрелы в ногу.
Если бы это так не раздражало, то было бы довольно забавным. Но давайте рассмотрим конкретные примеры!
«Этот API тоже использует OAuth 2.0, и мы создали его несколько недель назад. Наверно, до завтра я справлюсь» – знаменитые слова стажёра
OAuth — очень большой стандарт. На официальном сайте OAuth 2.0 [11] сейчас указано 17 разных RFC (определяющих стандарт документов), вместе описывающих принцип работы OAuth 2. В них раскрывается всё, от фреймворка OAuth и токенов Bearer до моделей угроз и JWT приватных ключей.
«Но ведь не все эти RFC важны для простой авторизации по токенам при помощи API?», — спросите вы.
Да, вы правы. Давайте сосредоточимся только на том, что релевантно для типичного примера доступа третьей стороне при помощи API:
Если вы думаете, что это всё равно слишком сложно и требует долгого изучения, то мы склонны с вами согласиться.
И большинство команд, разрабатывающих публичные API, наверно, тоже с этим согласно. Вместо реализации полного подмножества OAuth 2.0 они просто реализуют части OAuth, которые, по их мнению, будут необходимы в сценарии использования их API. Это приводит к созданию длинных страниц с описаниями того, как работает OAuth в конкретном API. Но мы вряд ли можем их винить; они руководствовались только самыми лучшими побуждениями. А если бы они попытались реализовать стандарт целиком, то документация представляла бы собой небольшую книгу!

Поток authorization_code OAuth в Salesforce. Что может не понравиться в этом чётком и наглядном объяснении процесса из десяти этапов?
Проблема в том, что каждый имеет слегка отличающееся понимание того, какое подмножество OAuth релевантно для него, поэтому в результате получается множество разных (под-)реализаций.
Так как каждый API реализует собственное подмножество OAuth, мы быстро попадаем в ситуацию, когда приходится внимательно читать длинные страницы документации по OAuth:
https://accounts.zoho.com, европейцы — на https://accounts.zoho.eu, а индийцы — на https://accounts.zoho.in. И так далее.
Этот список можно продолжать ещё долго, но надеюсь, смысл вы поняли.

OAuth слишком сложен; давайте создадим более простую версию OAuth, в которой есть всё, что нам нужно!
Даже несмотря на обширность стандарта OAuth, многие API, похоже, всё равно находят в нём отсутствие нужных им функций. Часто мы встречаемся с проблемой необходимости для работы с API дополнительных данных наряду с «access_token». Разве не было бы здорово, если бы эти дополнительные данные могли возвращаться вместе с access_token в потоке OAuth?
Мы и в самом деле считаем это хорошей идеей; или, по крайней мере, она получше, чем заставлять пользователей потом выполнять изощрённые запросы к API для получения этой информации (да, мы о тебе, Jira). Но это означает, что необходимо более нестандартное поведение, которое специально требуется реализовывать для каждого API.
Вот небольшой список нестандартных расширений, которые нам встречались:
Ради краткости и простоты мы опустим множество не очень стандартных потоков OAuth, с которыми нам приходилось сталкиваться.
Отлаживать распределённые системы всегда сложно. Ещё сложнее это делать, когда сервис, с которым ты работаешь, использует неопределённые и обобщённые сообщения об ошибках.
У OAuth2 есть стандартизованные сообщения об ошибках [15], но они не более информативны, чем пример из заголовка (который, кстати, является одним из рекомендованных сообщений об ошибках из стандарта OAuth).
Возможно, вы заявите, что OAuth — это стандарт, а для каждого API есть документация, так что же тут отлаживать?
Многое. Не могу передать, насколько часто в документации присутствуют ошибки. Или отсутствуют подробности. Или она не обновлялась с последним изменением. Или вы что-то упустили при первом её изучении. Добрые 80% реализуемых нами потоков OAuth имеют проблемы в первой реализации и требуют отладки.
Некоторые потоки разваливаются, казалось бы, по случайным причинам: например, LinkedIn OAuth разваливается при передаче параметров PKCE. Какую же ошибку мы получаем? «client error — invalid OAuth request». И о чём же она нам говорит? Нам потребовался час, чтобы понять, что поток ломается из-за параметров PKCE (опциональных, которые обычно игнорируют).
Ещё одна распространённая ошибка заключается в передаче scope, не совпадающих с теми, которые вы предварительно зарегистрировали с приложением. (Предварительно регистрируемые scope? Да, сегодня многие API требуют их.) Часто это приводит к получению обобщённого сообщения о проблеме с scope. Да уж.
Если вы надстраиваете чужую систему, используя её API, то вы, вероятно, находитесь в неудобном положении. Клиенты просят реализовать интеграцию, потому что они уже пользуются другой системой. И вам нужно удовлетворить их потребности.
Если честно, многие API достаточно либеральны и предоставляют простые самообслуживающиеся потоки регистрации, позволяющие разработчикам регистрировать свои приложения и использовать OAuth. Однако некоторые из самых популярных API требуют проверки, прежде чем приложение станет публичным и с ним можно будет работать пользователям. Повторюсь, ради справедливости нужно сказать, что большинство процессов проверки вполне разумны и их выполнение требует всего нескольких дней. В целом, с точки зрения качества и безопасности конечных пользователей они приносят пользу.
Однако в некоторых печальных случаях проверка затягивается на месяцы и даже требует подписания договоров об участии в прибыли:
С обнаружением разных видов атак и эволюцией веб-технологий стандарт OAuth тоже менялся. Если вы стремитесь реализовать современные рекомендации по безопасности, то у рабочей группы OAuth есть для вас довольно длинное руководство [17]. А если работаете с API, который и сегодня использует OAuth 1.0a, то поймёте, что обратная совместимость — это проблема, которую нужно решать постоянно.
К счастью, уровень защиты с каждой итерацией повышается, но часто за это приходится расплачиваться дополнительным трудом разработчиков. Грядущий стандарт OAuth 2.1 может сделать некоторые из современных рекомендаций обязательными и включает в себя обязательный PKCE (сегодня его требуют очень немногие API), а также дополнительные ограничения на токены обновления.
Самое важное заявленное изменение, вероятно, будет связано с истечением срока действия и с развитием токенов обновления. На поверхности процесс кажется простым: когда истекает срок действия токена доступа, мы обновляем его при помощи токена обновления и сохраняем новый токен доступа и токен обновления.
Однако в реальности, когда мы реализуем это, нужно учесть следующее:
К сожалению, мы затронули только малую часть аспектов реализации OAuth. Запустив поток OAuth и начав получать токены доступа, мы должны ещё подумать о следующем:
Пол-лимона подарков от RUVDS. Отвечай на вопросы и получай призы 🍋 [18]
Автор:
ru_vds
Источник [19]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/384646
Ссылки в тексте:
[1] есть: https://oauth.net/code/nodejs/
[2] клиентские библиотеки: https://oauth.net/code/php/
[3] практически: https://oauth.net/code/java/
[4] на всех: https://oauth.net/code/python/
[5] языках: https://oauth.net/code/go/
[6] программирования: https://oauth.net/code/rust/
[7] которые: https://oauth.net/code/dotnet/
[8] можно: https://oauth.net/code/kotlin/
[9] представить: https://oauth.net/code/swift/
[10] других OAuth API.: https://docs.nango.dev/providers
[11] официальном сайте OAuth 2.0: https://oauth.net/2/
[12] официальных параметров OAuth: https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml
[13] localhost: http://localhost
[14] существуют решения для перенаправления OAuth на localhost: https://www.nango.dev/blog/oauth-redirects-on-localhost-with-https
[15] стандартизованные сообщения об ошибках: https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
[16] стать партнёром Xero: https://developer.xero.com/documentation/xero-app-store/app-partner-guides/app-partner-steps/
[17] довольно длинное руководство: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics
[18] Пол-лимона подарков от RUVDS. Отвечай на вопросы и получай призы 🍋: https://habr.com/ru/specials/731732/
[19] Источник: https://habr.com/ru/companies/ruvds/articles/734204/?utm_source=habrahabr&utm_medium=rss&utm_campaign=734204
Нажмите здесь для печати.