oauth сервер на php
Oauth сервер на php
PHP OAuth 2.0 Server
league/oauth2-server is a standards compliant implementation of an OAuth 2.0 authorization server written in PHP which makes working with OAuth 2.0 trivial. You can easily configure an OAuth 2.0 server to protect your API with access tokens, or allow clients to request new access tokens and refresh them.
Out of the box it supports the following grants:
The following RFCs are implemented:
This library was created by Alex Bilbie. Find him on Twitter at @alexbilbie.
The latest version of this package supports the following versions of PHP:
The openssl and json extensions are also required.
All HTTP messages passed to the server should be PSR-7 compliant. This ensures interoperability with other packages and frameworks.
The library documentation can be found at https://oauth2.thephpleague.com. You can contribute to the documentation in the gh-pages branch.
The library uses PHPUnit for unit tests.
We use Github Actions, Scrutinizer, and StyleCI for continuous integration. Check out our configuration files if you’d like to know more.
Contributions are always welcome. Please see CONTRIBUTING.md and CODE_OF_CONDUCT.md for details.
Bugs and feature request are tracked on GitHub.
If you have any questions about OAuth please open a ticket here; please don’t email the address below.
If you discover any security related issues, please email andrew@noexceptions.io instead of using the issue tracker.
This package is released under the MIT License. See the bundled LICENSE file for details.
This code is principally developed and maintained by Andy Millington.
Between 2012 and 2017 this library was developed and maintained by Alex Bilbie.
PHP OAuth 2.0 Server is one of many packages provided by The PHP League. To find out more, please visit our website.
Additional thanks go to the Mozilla Secure Open Source Fund for funding a security audit of this library.
The initial code was developed as part of the Linkey project which was funded by JISC under the Access and Identity Management programme.
About
A spec compliant, secure by default PHP OAuth 2.0 Server
Создание PHP OAuth-сервера
Если вы когда-либо интегрировались с другим API, который требует безопасности (например, Twitter), вы, вероятно, использовали сервис OAuth. В этой статье я расскажу, что нужно для создания своего собственного трехстороннего сервера OAuth, позволяющего, например, создать собственный защищенный API, который вы можете опубликовать публично.
Имея дело с OAuth, вы обычно увидите, что он реализован в виде сервера OAuth с двумя или тремя ножками. Основное различие между ними заключается в том, что двухсторонняя аутентификация не затрагивает другого пользователя. Например, если вы хотите получить доступ к информации Twitter определенного пользователя, вы должны использовать трехсторонний сервер, поскольку для пользователя в вашем приложении должен быть создан токен доступа, а не просто Twitter, предоставляющий вам токен. Мы сосредоточимся на трехногом разнообразии, поскольку оно более практично для использования в реальных условиях.
Понимание потока
При использовании трехстороннего сервера OAuth типичный процесс, который разработчик предпримет для реализации и использования сервиса, выглядит следующим образом:
Настройка базы данных
Создание OAuth-сервера
Давайте начнем писать сервер OAuth. Следующее является общим для остальной части нашего кода, поэтому я поместил его в отдельный файл include/common.php :
Файл добавляет дополнительный HTTP-заголовок к каждому запросу, чтобы сообщить клиентам, что это сервер OAuth. Обратите внимание, что он ссылается на services.xrds.php ; этот файл снабжен примером, который поставляется с библиотекой oauth-php. Вы должны скопировать его из example/server/www/services.xrds.php в корневой публичный каталог веб-сервера.
Следующие несколько строк кода устанавливают соединение с базой данных (информация о соединении должна обновляться в соответствии с вашими настройками) и создает новые экземпляры объектов OAuthStore и OAuthServer предоставляемых библиотекой.
Настройка для сервера OAuth завершена, и сервер готов к полной реализации. В остальных примерах файл includes/common.php должен включаться каждый раз для создания экземпляра сервера.
Разрешение регистрации
По завершении регистрации выводятся новый потребительский ключ пользователя и секретный ключ потребителя. Эти значения должны быть сохранены пользователем для дальнейшего использования.
Теперь, когда пользователь зарегистрирован, он может начать делать запросы на токен доступа!
Генерация токена запроса
Метод requestToken() заботится о проверке того, что пользователь предоставил действительный ключ и подпись потребителя. Если запрос действителен, возвращается новый токен запроса.
Обмен токена запроса на токен доступа
Страница входа должна получить пользователя из таблицы пользователей. oauth_token идентификатор пользователя (вместе с oauth_token ) oauth_token в метод authorizeVerify() предоставляемый библиотекой. Предполагая, что пользователь авторизовал приложение, идентификатор вошедшего в систему пользователя затем связывается с ключом потребителя, что позволяет ему обеспечить безопасный доступ к данным этого пользователя.
Необходимая логика базового login.php может выглядеть следующим образом:
После того, как пользователь войдет в систему, он будет перенаправлен обратно на веб-сайт потребителя-разработчика (через параметр oauth_callback ) с действительным токеном. Этот токен и ключ проверки могут затем использоваться в обмене на действительный токен доступа.
Основной файл access_token.php выглядит следующим образом:
Подтверждение запроса
На этом этапе сервер OAuth запущен и работает. Но нам все еще нужно убедиться, что запрос содержит действительную подпись OAuth. Я создал основной тестовый файл, который делает именно это:
В этом примере, если запрос подтвержден, я просто отображаю идентификатор пользователя, который вошел в систему. Я бы предложил создать метод многократного использования, содержащий этот код, для любых вызовов API, требующих безопасности.
Тестирование OAuth-сервера
Наконец, пришло время протестировать сервер OAuth. Ниже приведен простой тестовый файл, который выполняет вышеуказанные шаги, чтобы потребовать от пользователя входа в систему и выполняет безопасный запрос:
OAuth требует, чтобы к каждому запросу добавлялись метки времени и подписи, и эта библиотека снова сделает это за нас.
Первая часть приведенного выше кода — это информация о конфигурации, которая должна быть обновлена в соответствии с вашими потребностями. Идентификатор пользователя, ключ потребителя и секретный ключ потребителя генерируются во время процесса регистрации на сервере.
Как описано во время ознакомления с OAuth-сервером с тремя ножками, в вышеуказанном тестовом файле выполняется следующий процесс:
Резюме
На этом этапе вы должны знать, как создать базовый сервер OAuth. Используя файл test_request.php качестве примера, вы можете начать создавать дополнительные функции, защищенные с помощью Oauth! Если вы хотите поиграть с некоторым кодом, полный исходный код этой статьи доступен на GitHub.
OAuth 2.0 простым и понятным языком
На хабре уже писали про OAuth 1.0, но понятного объяснения того, что такое OAuth 2.0 не было. Ниже я расскажу, в чем отличия и преимущества OAuth 2.0 и, как его лучше использовать на сайтах, в мобильных и desktop-приложениях.
Что такое OAuth 2.0
OAuth 2.0 — протокол авторизации, позволяющий выдать одному сервису (приложению) права на доступ к ресурсам пользователя на другом сервисе. Протокол избавляет от необходимости доверять приложению логин и пароль, а также позволяет выдавать ограниченный набор прав, а не все сразу.
Чем отличаются OpenID и OAuth
Не смотря на то, что объяснений на эту тему уже было много, она по-прежнему вызывает некоторое непонимание.
OpenID предназначен для аутентификации — то есть для того, чтобы понять, что этот конкретный пользователь является тем, кем представляется. Например, с помощью OpenID некий сервис Ололо может понять, что зашедший туда пользователь, это именно Рома Новиков с Mail.Ru. При следующей аутентификации Ололо сможет его опять узнать и понять, что, это тот же Рома, что и в прошлый раз.
OAuth же является протоколом авторизации, то есть позволяет выдать права на действия, которые сам Ололо сможет производить в Mail.Ru от лица Ромы. При этом Рома после авторизации может вообще не участвовать в процессе выполнения действий, например, Ололо сможет самостоятельно заливать фотографии на Ромин аккаунт.
Как работает OAuth 2.0
Как и первая версия, OAuth 2.0 основан на использовании базовых веб-технологий: HTTP-запросах, редиректах и т. п. Поэтому использование OAuth возможно на любой платформе с доступом к интернету и браузеру: на сайтах, в мобильных и desktop-приложениях, плагинах для браузеров…
Ключевое отличие от OAuth 1.0 — простота. В новой версии нет громоздких схем подписи, сокращено количество запросов, необходимых для авторизации.
Авторизация для приложений, имеющих серверную часть
Пример
Здесь и далее примеры приводятся для API Mail.Ru, но логика одинаковая для всех сервисов, меняются только адреса страниц авторизации. Обратите внимание, что запросы надо делать по HTTPS.
Редиректим браузер пользователя на страницу авторизации:
Здесь и далее, client_id и client_secret — значения, полученные при регистрации приложения на платформе.
После того, как пользователь выдаст права, происходит редирект на указанный redirect_uri:
Обратите внимание, если вы реализуете логин на сайте с помощью OAuth, то рекомендуется в redirect_uri добавлять уникальный для каждого пользователя идентификатор для предотвращения CSRF-атак (в примере это 123). При получении кода надо проверить, что этот идентификатор не изменился и соответствует текущему пользователю.
Используем полученный code для получения access_token, выполняя запрос с сервера:
Обратите внимание, что в последнем запросе используется client_secret, который в данном случае хранится на сервере приложения, и подтверждает, что запрос не подделан.
В результате последнего запроса получаем сам ключ доступа (access_token), время его «протухания» (expires_in), тип ключа, определяющий как его надо использовать, (token_type) и refresh_token о котором будет подробнее сказано ниже. Дальше, полученные данные можно использовать для доступа к защищенным ресурсам, например, API Mail.Ru:
Авторизация полностью клиентских приложений
Пример
Открываем браузер со страницей авторизации:
После того, как пользователь выдаст права, происходит редирект на стандартную страницу-заглушку, для Mail.Ru это connect.mail.ru/oauth/success.html:
Приложение должно перехватить последний редирект, получить из адреса acess_token и использовать его для обращения к защищенным ресурсам.
Авторизация по логину и паролю
Авторизация по логину и паролю представляет простой POST-запрос, в результате которого возвращается access token. Такая схема не представляет из себя ничего нового, но вставлена в стандарт для общности и рекомендуется к применению только, когда другие варианты авторизации не доступны.
Пример
Восстановление предыдущей авторизации
Обычно, access token имеет ограниченный срок годности. Это может быть полезно, например, если он передается по открытым каналам. Чтобы не заставлять пользователя проходить авторизацию после истечения срока действия access token‘а, во всех перечисленных выше вариантах, в дополнение к access token‘у может возвращаться еще refresh token. По нему можно получить access token с помощью HTTP-запроса, аналогично авторизации по логину и паролю.
Пример
Минусы OAuth 2.0
Во всей этой красоте есть и ложка дегтя, куда без нее?
OAuth 2.0 — развивающийся стандарт. Это значит, что спецификация еще не устоялась и постоянно меняется, иногда довольно заметно. Так, что если вы решили поддержать стандарт прямо сейчас, приготовьтесь к тому, что его поддержку придется подпиливать по мере изменения спецификации. С другой стороны, это также значит, что вы можете поучаствовать в процессе написания стандарта и внести в него свои идеи.
Безопасность OAuth 2.0 во многом основана на SSL. Это сильно упрощает жизнь разработчикам, но требует дополнительных вычислительных ресурсов и администрирования. Это может быть существенным вопросом в высоко нагруженных проектах.
Заключение
OAuth — простой стандарт авторизации, основанный на базовых принципах интернета, что делает возможным применение авторизации практически на любой платформе. Стандарт имеет поддержку крупнейших площадок и очевидно, что его популярность будет только расти. Если вы задумались об API для вашего сервиса, то авторизация с использованием OAuth 2.0 — хороший выбор.
An OAuth2 Server Library for PHP
Implement an OAuth 2.0 Server cleanly into your PHP application. Download the Code from GitHub to get started.
Requirements
PHP 5.3.9+ is required for this library. However, there is a stable release and development branch for PHP 5.2.x-5.3.8 as well.
Installation
This library follows the zend PSR-0 standards. A number of autoloaders exist which can autoload this library for that reason, but if you are not using one, you can register the OAuth2\Autoloader :
Using Composer? Execute the following command:
composer.phar require bshaffer/oauth2-server-php «^1.10»
This will add the requirement to the composer.json and install the library.
It is highly recommended you check out the v1.10.0 tag to ensure your application doesn’t break from backwards-compatibility issues. However, if you’d like to stay on the bleeding edge of development, you can set this to dev-master instead.
Get Started With This Library
Looking through the cookbook examples is the best way to get started. For those who just skim the docs for code samples, here is an example of a bare-bones OAuth2 Server implementation:
See Main Concepts for more information on how this library works.
Learning the OAuth2.0 Standard
If you are new to OAuth2, I highly recommend the OAuth in 8 Steps screencast from Knp University:
Additionally, take some time to click around on the OAuth2 Demo Application and view the source code for examples using a variety of grant types.
Also, Auth0 provides a very nice layer for implementing OAuth2.0 for PHP applications.
Finally, consult the official OAuth2.0 documentation for the down-and-dirty technical specifications.
Contact
The best way to get help and ask questions is to file an issue. This will help answer questions for others as well.
If for whatever reason filing an issue does not make sense, contact Brent Shaffer (bshafs gmail com)
Архитекторы ничего не выдумывают. Они трансформируют реальность.
Много всего уже сказано и написано про фреймворк авторизации OAuth 2.0 с 2012 года. И, казалось бы, все давно его знают, используют, все должно работать надежно и безопасно.
Но, как обычно, на практике все иначе. В работе в реальности приходится сталкиваться с небезопасными реализациями процессов авторизации и аутентификации. Огорчает, что по статистике Россия занимает непочетное первое место по своей уязвимости.
Почему же так получается? Предлагаю вместе со мной и авторами драфта OAuth 2.1 от июля 2020 года сделать небольшую работу над ошибками. Это и будет отражением, на мой взгляд, того, по какому пути развития идет фреймворк OAuth 2.
Также спешу предупредить строгого читателя, что в данной статье я затрону только вопросы и сложности, связанные с реализациями по OAuth 2.0. Я не ставлю цели обозначить все проблемы с безопасностью в России в ИТ, и почему этот вопрос требует особого пристального внимания сегодня.
Введение
Стоит ли винить во всем разработчиков, как это принято делать чаще всего? На мой взгляд, не стоит. У разработчика часто стоит задачей реализовать ту или иную функциональность по неким требованиям. Посмотрим же внимательнее на OAuth 2.0.
Фреймворк предлагает воспользоваться правилами по организации потоков авторизации:
«Что в описании стандарта может приводить к небезопасным реализациям на практике?»
Я пока оставлю этот вопрос открытым, и предлагаю читателю самостоятельно при дальнейшем изучении OAuth 2.0 и прочтении статьи делать свои выводы. На протяжении этой статьи я же буду приводить свое видение ответа на этот вопрос.
Понятия и термины
Перед рассмотрением отдельно каждого из потоков, дадим определения базовой терминологии, используемой в стандарте (читателю, знакомому с терминологией OAuth 2.0, данный абзац можно пропустить).
Термин OAuth 2.0 Authorization Framework | Описание из OAuth 2.0 | Пример |
---|---|---|
Resource owner (Владелец ресурса) | Абстрактная сущность, предоставляющая доступ к защищенном ресурсу. Если в качестве этой роли выступает человек, то его называют конечным пользователем (end-user). | Например, человек, предоставляющий доступ к своим персональным данным, хранящимся на сервере. |
Resource server (Сервер ресурсов) | Сервер, на котором размещаются защищенные ресурсы, принимающий и отвечающий на защищенные запросы к ресурсам с использованием токена доступа (access token). | Например, сервер KeyCloak, предоставляющий доступ к данным пользователя через REST-сервис (UserInfo Endpoint) |
Client (Клиентское приложение) | Приложение, выполняющее запросы ресурсов от имени владельца ресурса и с его разрешения. Термин «клиент» не подразумевает каких-либо конкретных характеристик реализации в стандарте (например, выполняется ли приложение на сервере, рабочем столе или других устройствах). | Web Application, Desktop Native Application, Mobile Native Application, SPA App, Javascript application |
Authorization server (Сервер авторизации) | Сервер, выдающий клиенту токены доступа после успешной аутентификации владельца ресурса и авторизации. | Например, сервер KeyCloak (если говорить про открытое решение KeyCloak, то он может выступать как сервером ресурсов, так и сервером авторизации одновременно. |
Критический взгляд на OAuth 2.0
Изучая последовательно стандарт, можно столкнуться с рядом неоднозначных рекомендаций, что, в прочем, не является редким явлением зачастую в документации. Предлагаю сейчас и заняться выявлением этих несоответствий. Хотя кому-то я могу показаться излишне придирчивой. Я этого не исключаю и буду рада услышать встречное мнение читателя.
Authorization Code Grant
Рассмотрим первый из наиболее распространенных в реализации потоков с момента создания стандарта: Authorization Code Grant. В самом начале стандарта его разработчики предлагают ознакомиться с общим, объединяющим все потоки документа представлением. А далее уже рассматривается каждый индивидуально и, в частности, Authorization Code Grant (from the OAuth 2.0 Authorization Framework). Но что мы видим:
На представлении потока Authorization Code Grant почему-то отсутствует ресурсный сервер. Наверное, у многих потребителей стандарта может возникнуть вопрос, что же делать дальше с полученным токеном?
На практике периодически встречалась с реализацией, когда сам поток реализовывали корректно, а далее все запросы к сервисам просто шли непосредственно из браузера (User-Agent) без какого-либо использования токена для защиты. Либо с использованием токена, который от клиента (Client) пробрасывался в браузер сначала, а из браузера (User-Agent) шли запросы к сервисам. Токен, естественно, можно просто было просмотреть в самом браузере.
В стандарте в самом начале есть описание, как использовать токен в общем описании потока. Но как показала практика, не хватает этой детализации и в описании Authorization Code Grant.
Давайте добавим ресурсный сервер для устранения этой неточности в описание потока (на рисунках я буду приводить только положительные сценарии, чтобы не перегружать диаграммы условиями):
Также стоит отдельно заметить, что если серверная часть клиент-серверного приложения выполняет запросы к Resource Server внутри одной защищенной сети, то использование Access токена можно опустить. Запросы будут защищены в рамках одной сети, а Authorization Code Grant будет использоваться непосредственно только для аутентификации пользователя.
Implicit Grant
«These clients are typically implemented in a browser using a scripting language such as JavaScript.»
«Because the access token is encoded into the redirection URI, it may be exposed to the resource owner and other applications residing on the same device.»
«See Sections 10.3 and 10.16 for important security considerations when using the implicit grant.»
» For public clients using implicit flows, this specification does not provide any method for the client to determine what client an access token was issued to.»
А затем описание с рекомендациями, как мы могли бы сами о себе позаботиться. Т.е. получаем, что как бы поток в стандарте описан, но его описание ничего общего с «безопасностью» не имеет. Т.е. сами по себе описываемые последовательности запросов в фреймворке авторизации не гарантируют безопасного взаимодействия. Могут потребоваться дополнительные меры по ее организации.
И OAuth 2.0 — это не всегда про безопасность, несмотря на устоявшееся мнение. Но все ли читают рекомендации в сносках?
Resource Owner Password Credentials Grant
«The authorization server should take special care when enabling this grant type and only allow it when other flows are not viable.»
Думаю, эта фраза многих уберегла от реализации данного потока на практике. Не будем долго задерживаться на Resource Owner Password Credentials Grant.
Client Credentials Grant
«A refresh token SHOULD NOT be included.»
Но что значит «не следует»? Т.е. вроде как, и можно использовать, т.е. какие-то сценарии могут потребовать его наличия? А на практике мы имеем, что системы, которые реализуются по OAuth 2.0, вынуждены реализовывать такую возможность, так как стандартом она не исключается.
И здесь надо вспомнить, для чего, в принципе, были придуманы «Refresh token» и «Access token».
У Access token есть ограниченный срок действия, и когда он истекает, клиент (Client) в обмен на «Refresh token» запрашивает новый «Access token». «Refresh token» всегда может использоваться один и тот же, либо с каждым новым «Access token» передаваться и новый «Refresh token» должен, что безопаснее, но сложнее в реализации.
Если вернуться к описанию потока Authorization Code Grant, то там мы можем увидеть реальную необходимость его использования: в случае, когда по каким-либо причинам злоумышленнику удалось украсть Access token в обмен на код авторизации (это возможно, так как код авторизации передается приложению через обмен с браузером (или другим пользовательским агентом), а Client ID и Secret по каким-то причинам не используются при запросе токена доступа (или их смогли украсть ранее), то из-за ограниченности периода действия Access token, у злоумышленника будет столько времени навредить, сколько действует Access token, и пока в обмен на Refresh token не будет запрошен новый Access token доверенным клиентом.
И да, Authorization Code Grant тоже не гарантирует полной безопасности, хотя при его корректной реализации, злоумышленнику не так то просто вклиниться в поток и что-то украсть или сломать, особенно еще и с учетом проверок пользовательских и клиентских сессий, которые хранятся обычно на сервере авторизации, и о которых я ничего не рассказываю здесь.
А если мы посмотрим на Client Credentials Flow, то здесь, если злоумышленник украдет Client ID и Secret, то Refresh token нам не навредит, но уже никак и не поможет. Поэтому мы имеем избыточность и излишнюю сложность в реализациях.
Итак, мы с некой долей скептицизма рассмотрели авторизационные потоки, которые нам предлагает фреймворк OAuth 2.0. Давайте же теперь разбираться и отвечать на вопрос, поставленный в заголовке к самой статье. В каком направлении и как развивается OAuth 2.0?
За период, начиная с момента перевода OAuth 2.0 из черновика в статус стандарта, до настоящего времени разработчики стандарта продолжали активно делать работу над ошибками, которая появлялась в свет в виде новых RFC и черновиков в дополнение к OAuth 2.0:
(1) Потоки Implicit grant (response_type=token) и Resource Owner Password Credentials исключаются из документа.
Clients MUST use «code_challenge» and «code_verifier» and authorization servers MUST enforce their use except under the conditions described in Section 9.8. In this case, using and enforcing «code_challenge» and «code_verifier» as described in the following is still RECOMMENDED.
Clients MUST prevent injection (replay) of authorization codes into the authorization response by attackers. To this end, using «code_challenge» and «code_verifier» is REQUIRED for clients and authorization servers MUST enforce their use, unless both of the following criteria are met:
* The client is a confidential or credentialed client.
* In the specific deployment and the specific request, there is reasonable assurance for authorization server that the client implements the OpenID Connect «nonce» mechanism properly.
(3) Redirect URIs должны будут всегда явно задаваться на сервере.
(4) Refresh токены для публичных клиентов должны ограничиваться, либо использоваться не более 1 раза.
С учетом (1) и (2), наибольшего внимания, на мой взгляд, заслуживает Proof Key for Code Exchange сейчас.
Как мы и говорили выше, все чаше мы уже отходим от реализаций классических проверенных временем клиент-серверных архитектур (хотя я сама призываю всегда не следовать за модой, а выбирать решение в зависимости от поставленной задачи). И разработчики RFC предлагают измененные решения для трансформирующейся реальности.
К сожалению, в OAuth 2.1 представления потоков не изменились, дополнились только описания к ним. Поэтому я не буду уже приводить вид из стандарта (с теми же граблями в виде отсутствующего ресурсного сервера), а сразу сделаю боле детальное описание.
На диаграмме последовательностей вызовов ниже приведен случай для приложения без классического бэкенда (намеренно указывается JSClient). А также видим, что в случае, когда у нас появляется и ресурсный сервер на диаграмме, то мы вынуждены добавлять API шлюз для выполнения более сложных проверок (URI, валидность токена, идентификацию клиента и т.д.) не ресурсным сервером:
Памятка для разработчиков
Имеющийся сейчас у меня опыт работы с системами, реализующими OAuth 2, хотела бы оставить в статье, так как надеюсь, что он может оказаться кому-то полезен и позволит качественнее защищать наши с вами данные в сети.
Позволю себе обозначенные правила к авторизационным потокам и приложениям, которые их реализуют, разложить в виде матрицы принятия решений:
Приложение по OAuth 2.0 | OAuth2/OIDC Authorization code Grant | OAuth2/OIDC Authorization code Grant with PKCE | Client Credentials Grant |
---|---|---|---|
Web application with a Confidential Client | + | + | + |
User-agent-based application: JavaScript Applications without a Backend with a Public Client | — | + | — |
User-agent-based application: Javascript application with a Backend with a Confidential Client | + | + | + |
Application without an authentification flow with a Confidential Client | — | — | + |
Приведенные выше заметки, на мой взгляд, могут быть полезны при составлении чек-листа требований к системам, отвечающим за безопасность процессов авторизации/аутентификации пользователей. Возможно, я что-то важное, на ваш взгляд, упускаю. Поможете мне дополнить список требований и ограничений?
Заключение
В заключении, думаю, стоит заметить, что исходя из той динамики, о которой говорилось выше по дополнению OAuth 2.0 RFC и драфтами в течение 9 лет, мы можем ожидать, что со временем, все-таки наши системы станут безопаснее и надежнее. Мы видим, что стандарт становится строже, но в то же время, он и неизбежно трансформируется под влиянием тенденций в разработке. Хотя бдительность я бы предложила не терять и не расслабляться: с новыми требованиями мы можем столкнуться и с новыми нелепыми реализациями из-за двусмысленности добавленных формулировок.