В чем разница между кодом авторизации OAuth и неявными рабочими процессами? Когда использовать каждый?
=======================================================================================================

OAuth 2.0 имеет несколько рабочих процессов. У меня есть несколько вопросов относительно этих двух.

* **поток кода авторизации**. Пользователь регистрируется в клиентском приложении, сервер авторизации возвращает в приложение код авторизации. Затем приложение обменивает код авторизации для токена доступа.
* **Неявный поток грантов**. Пользователь регистрируется в клиентском приложении, сервер авторизации напрямую обращается к токену доступа к клиентскому приложению.

В чем разница между двумя подходами в плане безопасности? Какой из них более безопасен и почему?

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

Различные веб-сайты говорят, что поток кода авторизации используется, когда клиентское приложение может хранить учетные данные в безопасности. Почему?

 

 `access_token` - это то, что вам нужно вызвать защищенный ресурс (API). В потоке авторизационного кода есть два шага:

* Пользователь должен аутентифицировать и вернуть `code` потребителю API (называемому "Клиент" ).
* "Клиент" API (обычно ваш веб-сервер) обменивает `code`, полученный в # 1 для `access_token`, аутентифицируя себя с помощью `client_id` и `client_secret`
* Затем он может вызвать API с помощью `access_token`.

Итак, существует двойная проверка: пользователь, который владеет ресурсами, просматривал API и клиент, используя API (например, веб-приложение). Оба проверяются для доступа. Обратите внимание на "авторизацию" OAuth здесь: пользователь предоставляет доступ к своему ресурсу (через `code`, возвращенному после аутентификации) в приложение, приложение получает `access_token` и вызывает имя пользователя.

 (function(w, d, n, s, t) {
 w[n] = w[n] || [];
 w[n].push(function() {
 Ya.Context.AdvManager.render({
 blockId: "R-A-248011-3",
 renderTo: "yandex\_rtb\_R-A-248011-3",
 async: true
 });
 });
 t = d.getElementsByTagName("script")[0];
 s = d.createElement("script");
 s.src = "//an.yandex.ru/system/context.js";
 s.async = true;
 t.parentNode.insertBefore(s, t);
 })(this, this.document, "yandexContextAsyncCallbacks");

В неявном потоке шаг 2 опущен. Поэтому после аутентификации пользователя возвращается `access_token`, который вы можете использовать для доступа к ресурсу. API не знает, кто вызывает этот API. Любой, у кого есть `access_token`, может, в то время как в предыдущем примере только веб-приложение (оно внутренне нормально не доступно для всех).

Неявный поток обычно используется в сценариях, где сохранение `client id` и `client secret` не рекомендуется (например, устройство, хотя многие это делают). То, что означает отказ от ответственности. Люди имеют доступ к клиентскому коду и поэтому могут получить учетные данные и притворяться, что станут клиентами ресурсов. В неявном потоке все данные являются изменчивыми, и в приложении ничего не хранится.

 

Я добавлю что-то здесь, о котором я не думаю, ясно сказано в приведенных выше ответах:

* **Authorization-Code-Flow позволяет конечный токен доступа никогда не появляться и никогда не храниться на компьютере с браузером/приложением**. Временный код авторизации предоставляется машине с браузером/приложением, которое затем отправляется на сервер. Затем сервер может обменять его с помощью токена доступа и получить доступ к API и т.д. Пользователь с браузером получает доступ к API только через сервер с токеном.
* Неявный поток может включать только две стороны, а  **конечный токен доступа хранится на клиенте с браузером/приложением.**. Если этот браузер/приложение скомпрометировано, так это их аутентификационный токен, который может быть опасно.

 (function(w, d, n, s, t) {
 w[n] = w[n] || [];
 w[n].push(function() {
 Ya.Context.AdvManager.render({
 blockId: "R-A-248011-4",
 renderTo: "yandex\_rtb\_R-A-248011-4",
 async: true
 });
 });
 t = d.getElementsByTagName("script")[0];
 s = d.createElement("script");
 s.src = "//an.yandex.ru/system/context.js";
 s.async = true;
 t.parentNode.insertBefore(s, t);
 })(this, this.document, "yandexContextAsyncCallbacks");

  **tl; dr** не использовать неявный поток, если вы не доверяете машине пользователей для хранения токенов, но доверяете своим собственным серверам.

 

Различие между ними заключается в следующем:

* В потоке кода авторизации код возвращается с помощью?? для чтения на стороне сервера, тогда стороне сервера необходимо предоставить секрет клиента на этот раз token url, чтобы получить токен как объект json с сервера авторизации. Он используется, если у вас есть сервер приложений, который может справиться с этим, и хранить токен пользователя с его профилем в своей собственной системе и в основном используется для обычных мобильных приложений.

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

 

Неявное предоставление похоже на грант кода авторизации с двумя различными отличиями.

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

Во-вторых, вместо сервера авторизации, возвращающего код авторизации, который обменивается на токен доступа, сервер авторизации возвращает токен доступа.

Подробнее здесь
<http://oauth2.thephpleague.com/authorization-server/which-grant/>

 

 Неявный поток
==============

 Преимущества
-------------

* Проще всего реализовать

 Недостатки
-----------

* Доступ к токенам, видимым для браузера
* Происхождение токенов доступа не может быть определено
* Доступ к токенам доступа не может истекать (в соответствии с политикой Google).

---

 Поток кода авторизации
=======================

 Преимущества
-------------

* Наиболее безопасный
* Токены доступа и токены обновления могут быть созданы только в том случае, если известен общий секрет
* Могут быть улучшены новые функции безопасности и UX, когда они станут доступны

 Недостатки
-----------

* Необходимо реализовать несколько конечных точек auth

Образец цитирования: <https://developers.google.com/actions/develop/identity/oauth2-overview#supported_oauth_20_flows>

 

Позвольте мне кратко изложить пункты, которые я узнал из предыдущих ответов, и добавить некоторые из моих собственных понятий.

 Поток кода авторизации!!!
==========================

* Если у вас есть сервер веб-приложений, который действует как клиент OAuth
* Если вы хотите иметь долговременный доступ
* Если вы хотите иметь автономный доступ к данным
* когда вы отвечаете за вызовы api, которые делает ваше приложение
* Если вы не хотите терять токен OAuth
* Если вы не хотите, чтобы приложение запускалось через поток авторизации каждый раз, когда ему нужен доступ к данным. ПРИМЕЧАНИЕ. Неявный поток грантов не содержит токен обновления, поэтому, если сервер авторизации регулярно проверяет токены доступа, ваше приложение должно будет проходить через поток авторизации всякий раз, когда ему нужен доступ.

 Неявный поток грантов!!!
=========================

* Если у вас нет сервера веб-приложений для работы в качестве клиента OAuth
* Если вам не нужен долговечный доступ, то требуется только временный доступ к данным.
* Если вы доверяете браузеру, в котором работает ваше приложение, и существует ограниченная озабоченность по поводу того, что токен доступа будет протекать не доверенным пользователям.

 

С практической точки зрения (что я понял), Основная причина наличия потока кода Authz: 

* Поддержка токенов обновления (долгосрочный доступ приложениями от имени пользователя), не поддерживается в неявном: см. <https://tools.ietf.org/html/rfc6749#section-4.2>
* Поддержка страницы согласия, которая является местом, где владелец ресурсов может контролировать, какой доступ предоставить (вид страницы разрешений/авторизации, которую вы видите в google). То же самое не существует в неявном виде. См. Раздел: <https://tools.ietf.org/html/rfc6749#section-4.1>, point (B)

 "Сервер авторизации аутентифицирует владельца ресурса (через пользовательского агента) и устанавливает, предоставляет ли владелец ресурса или отклоняет запрос доступа клиента" 

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

 

> 
>   Какой из них более безопасный и почему?
> 
> 
> 

Они оба безопасны, это зависит от среды, в которой вы их используете.

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

Это просто. Ваш клиент не защищен. Давайте посмотрим на это подробнее.

Предположим, вы разрабатываете приложение для `Instagram API`, поэтому вы регистрируете свое приложение в `Instagram` и определяете, какой `API` вам нужен. `Instagram` предоставит вам `client_id` и `client_secrect`

На вашем веб-сайте вы создали ссылку, которая говорит. "Приходите и используйте мое приложение". При нажатии на это ваше веб-приложение должно выполнить **два** вызова `Instagram API`.

`First` отправляет запрос в `Instagram Authentication Server` с указанными ниже параметрами.

```
1. 'response_type' with the value 'code'
2. 'client_id' you have get from 'Instagram'
3. 'redirect_uri' this is a url on your server which do the second call
4. 'scope' a space delimited list of scopes
5. 'state' with a CSRF token. 

```

**Вы не отправляете `client_secret`**, вы не можете доверять клиенту (пользователю и его браузеру, которые пытаются использовать ваше приложение). Клиент может увидеть URL или java-скрипт и легко найти ваш `client_secrect`. Вот почему вам нужен еще один шаг.

Вы получаете `code` и `state`. `code` здесь `temporary` и не сохраняется нигде.

Затем вы делаете `second` вызов `Instagram API` (с вашего сервера)

```
 1. 'grant_type' with the value of 'authorization_code'
 2. 'client_id' with the client identifier
 3. 'client_secret' with the client secret
 4. 'redirect_uri' with the same redirect URI the user was redirect back to
 5. 'code' which we have already received.

```

Поскольку вызов сделан с нашего сервера, мы можем безопасно использовать `client_secret` (который показывает, как мы) с `code`, который показывает, что пользователь выдал `client_id` для использования ресурса.

В ответ у нас будет `access_token`