Понимание протокола OAuth2

Node.js внешний интерфейс

Статья впервые опубликована на:GitHub.com/US TB-Вуд, умри, о ты…

написать впереди

Вчера я поделился сторонним входом в систему и единым входом в группе, которая сосредоточилась на совместном использовании протокола oAuth2 в стороннем входе, и записал это здесь. Протокол oAuth — это открытый сетевой стандарт для авторизации, который в основном используется для решения стороннего входа, то есть так называемого стороннего входа, который фактически является авторизацией oAuth.

Что такое сторонний вход

Многие веб-сайты позволяют вам войти в систему, используя удостоверение стороннего веб-сайта, что называется «сторонним входом». Например, Zhihu и MOOC могут использовать для входа WeChat, QQ или Weibo. Если веб-сайт хочет получить доступ к стороннему входу в систему, ему необходимо использовать протокол oAuth.

Что такое оаут

oAuth — это открытый веб-стандарт для авторизации, который используется для авторизации сторонних приложений для получения пользовательских данных. Его конечной целью является выдача стороннему приложению чувствительного ко времени токена access_token.В соответствии с этим access_token стороннее приложение может получить соответствующие ресурсы пользователя, такие как аватар, псевдоним и адрес электронной почты. Сейчас все в основном используют версию 2.0.

Этот протокол oAuth2.0 является производным отRFC 6749Если вы хотите узнать более полную информацию, упомянутую в этой статье, вы можете нажать 👆Эта статья, чтобы понять. Давайте представим роли и процессы oAuth2.

Процесс согласования

Прежде чем подробно представить процесс протокола oAuth2, давайте кратко рассмотрим несколько ролей, чтобы облегчить последующее понимание.

  • Владелец ресурса, владелец ресурса, поскольку он запрашивает некоторую информацию об аватаре и никнейме пользователя, владелец ресурса обычно обращается к самому пользователю.
  • Клиент, клиент, такой как веб-сайт, приложение и т. д.
  • Сервер ресурсов, сервер ресурсов, сервер, на котором размещены защищенные ресурсы
  • Сервер авторизации, сервер авторизации, как правило, это приложение той же компании, что и сервер ресурсов, в основном используемое для обработки авторизации и выдачи токенов клиентам.
  • Пользовательский агент, пользовательский агент, обычно веб-браузер и приложение на мобильном телефоне.

Разобравшись с перечисленными выше ролями, давайте взглянем на процесс работы oAuth2.0.

 +--------+                               +---------------+
 |        |--(A)- Authorization Request ->|   Resource    |
 |        |                               |     Owner     |
 |        |<-(B)-- Authorization Grant ---|               |
 |        |                               +---------------+
 |        |
 |        |                               +---------------+
 |        |--(C)-- Authorization Grant -->| Authorization |
 | Client |                               |     Server    |
 |        |<-(D)----- Access Token -------|               |
 |        |                               +---------------+
 |        |
 |        |                               +---------------+
 |        |--(E)----- Access Token ------>|    Resource   |
 |        |                               |     Server    |
 |        |<-(F)--- Protected Resource ---|               |
 +--------+                               +---------------+

(A) Пользователь открывает клиент (Client), и клиент отправляет запрос авторизации на сервер авторизации (Resource Owner)

(Б) Пользователь соглашается авторизовать клиента (Клиент)

(C) Клиент использует предыдущую авторизацию для аутентификации на сервере аутентификации (сервере авторизации).

(D) После того, как сервер аутентификации пройдет аутентификацию, он выдаст клиенту токен (токен доступа).

(E) Клиент держит токен (токен доступа) и переходит к серверу ресурсов (серверу ресурсов), чтобы подать заявку на ресурсы.

(F) После того, как сервер ресурсов подтвердит токен, он возвращает защищенный ресурс клиенту (защищенный ресурс).

Способ авторизации

В OAUTH2 четыре метода авторизации определены для разных бизнес-сценариев:

  • Режим кода авторизации (код авторизации): Самый полный и строгий метод авторизации, сервер и клиент используются вместе, в основном для ситуации веб-сервера.
  • Упрощенный режим (неявный): в основном используется для мобильных приложений или чистых интерфейсных веб-приложений, в основном в случае отсутствия веб-сервера.
  • Режим пароля (учетные данные владельца ресурса): не рекомендуется, пользователи должны предоставить клиенту свою учетную запись и пароль, если клиент является их собственным приложением, это также возможно.
  • Режим клиента (учетные данные клиента): клиент аутентифицируется у «поставщика услуг» от своего имени, а не имени пользователя. Например, официальная учетная запись WeChat использует этот access_token для извлечения информации обо всех пользователях, которые последовали за ним, и докер для dockerhub вытягивать изображения и т. д.

Режим кода авторизации

 +----------+
 | Resource |
 |   Owner  |
 |          |
 +----------+
      ^
      |
     (B)
 +----|-----+          Client Identifier      +---------------+
 |         -+----(A)-- & Redirection URI ---->|               |
 |  User-   |                                 | Authorization |
 |  Agent  -+----(B)-- User authenticates --->|     Server    |
 |          |                                 |               |
 |         -+----(C)-- Authorization Code ---<|               |
 +-|----|---+                                 +---------------+
   |    |                                         ^      v
  (A)  (C)                                        |      |
   |    |                                         |      |
   ^    v                                         |      |
 +---------+                                      |      |
 |         |>---(D)-- Authorization Code ---------'      |
 |  Client |          & Redirection URI                  |
 |         |                                             |
 |         |<---(E)----- Access Token -------------------'
 +---------+       (w/ Optional Refresh Token)

Note: The lines illustrating steps (A), (B), and (C) are broken into two parts as they pass through the user-agent.

Режим кода авторизации показан на рисунке выше.Этот процесс является наиболее полным и строгим методом авторизации и подходит для веб-приложений с бэкендами. Его характеристикой является связь через фоновый сервер клиента и сервер аутентификации поставщика услуг. Его процесс выглядит следующим образом, если я хочу использовать github для доступа к стороннему входу в систему:

(A) Пользователь (Владелец ресурса) выбирает стороннее приложение (например, github) на пользовательском агенте (User-Agent, таком как веб-браузер, приложение) для входа в систему, и оно будет перенаправлено на авторизацию конечная точка github:

   https://github.com/login/oauth/authorize?
   response_type=code&
   client_id=your_code&
   redirect_uri=重定向的url&
   scope=read&
   state=uuid
поле описывать
response_type Обязательно, фиксируется как код в режиме кода авторизации
client_id Обязательно, однозначно идентифицирует клиента, идентификатор клиента, полученный при регистрации на github.
redirect_url URL-адрес перенаправления, зарегистрированный клиентом в github, пользователь перейдет к этому URL-адресу перенаправления, когда согласится или отклонит его.
scope Необязательно, запросите диапазон ресурсов, если есть несколько элементов, используйте несколько пробелов для разделения
state Рекомендуется, чтобы случайное число, сгенерированное клиентом, возвращалось сервером ресурсов для предотвращения атак CSRF.

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

(C) Затем github вернет код авторизации (Authorization Code) на redirect_uri (redirect uri).

redirect_uri?code=xxxxxxx
поле описывать
code требуется, код авторизации
state Параметры для предотвращения CSRF-атак

(D) Клиент (Клиент) после извлечения с помощью кода авторизации в URL-адресе, вы можете запросить токен на задней части github.

  https://github.com/login/oauth/access_token?
  client_id=your_code&
  client_secret=your_secret&
  grant_type=authorization_code&
  code=取出的code&
  redirect_uri=重定向的url
поле описывать
client_id Обязательно, уникальный идентификатор клиента, зарегистрированного в github
client_secret Обязательно, ключ, возвращаемый клиентом при регистрации на github
grant_type Обязательно, код_авторизации/код_обновления
code Требуется, код авторизации, извлеченный на предыдущем шаге
redirect_uri Обязательный адрес обратного вызова после завершения авторизации, который совпадает с зарегистрированным на github

(E). github возвращает AccessToken на адрес, указанный redirect_uri, который возвращается в формате JSON.

{
  "access_token":"xxxxxxx",
  "token_type":"bearer",
  "expires_in":3600,
  "refresh_token":"xxxxxxx"
}

Клиент может получить access_token на серверной части. В этом json также возвращается refresh_token. Этот refresh_token представляет собой токен, используемый для доступа к следующему обновлению. Срок действия refresh_token дольше, чем срок действия access_token. Когда срок действия access_token истекает, вы может обменять refresh_token на новый access_token.

упрощенный режим

Упрощенный режим в основном нацелен на чистые front-end приложения без back-end, в этом случае из-за отсутствия back-end процесс режима кода авторизации использовать нельзя, а access_token нужно хранить во фронте -конец.

 +----------+
 | Resource |
 |  Owner   |
 |          |
 +----------+
      ^
      |
     (B)
 +----|-----+          Client Identifier     +---------------+
 |         -+----(A)-- & Redirection URI --->|               |
 |  User-   |                                | Authorization |
 |  Agent  -|----(B)-- User authenticates -->|     Server    |
 |          |                                |               |
 |          |<---(C)--- Redirection URI ----<|               |
 |          |          with Access Token     +---------------+
 |          |            in Fragment
 |          |                                +---------------+
 |          |----(D)--- Redirection URI ---->|   Web-Hosted  |
 |          |          without Fragment      |     Client    |
 |          |                                |    Resource   |
 |     (F)  |<---(E)------- Script ---------<|               |
 |          |                                +---------------+
 +-|--------+
   |    |
  (A)  (G) Access Token
   |    |
   ^    v
 +---------+
 |         |
 |  Client |
 |         |
 +---------+

Note: The lines illustrating steps (A) and (B) are broken into two parts as they pass through the user-agent.

В основном на шаге B страница переходит на сайт github, и пользователь соглашается авторизовать клиента. github будет использовать токен в качестве параметра URL и вернется к адресу обратного вызова redirect_uri.

回调地址#token=xxxxxx

Обратите внимание, что местоположение токена — это привязка URL-адреса (фрагмент), а не строка запроса (строка запроса), потому что OAuth 2.0 позволяет URL-адресам перенаправления быть протоколом HTTP, поэтому существует «атака посредника». риск, и браузер перенаправляет. Когда точка привязки не отправляется на сервер, риск утечки токена снижается.

режим пароля

Если у вас высокий уровень доверия к приложению, RFC 6749 также позволяет пользователям напрямую сообщать приложению свое имя пользователя и пароль. Приложение использует ваш пароль для запроса токена, который называется «пароль».

+----------+
 | Resource |
 |  Owner   |
 |          |
 +----------+
      v
      |    Resource Owner
     (A) Password Credentials
      |
      v
 +---------+                                  +---------------+
 |         |>--(B)---- Resource Owner ------->|               |
 |         |         Password Credentials     | Authorization |
 | Client  |                                  |     Server    |
 |         |<--(C)---- Access Token ---------<|               |
 |         |    (w/ Optional Refresh Token)   |               |
 +---------+                                  +---------------+

        Figure 5: Resource Owner Password Credentials Flow

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

клиентский режим

Клиент аутентифицируется у «поставщика услуг» от своего имени, а не от имени пользователя. Например, общедоступная учетная запись WeChat использует access_token для получения информации обо всех пользователях, за которыми он следил, а докер для dockerhub извлекает изображение, и т.п.

 +---------+                                  +---------------+
 |         |                                  |               |
 |         |>--(A)- Client Authentication --->| Authorization |
 | Client  |                                  |     Server    |
 |         |<--(B)---- Access Token ---------<|               |
 |         |                                  |               |
 +---------+                                  +---------------+

                 Figure 6: Client Credentials Flow

Режим клиента, как следует из названия, означает, что клиент обращается к поставщику услуг для аутентификации от своего имени, а не от имени пользователя. Строго говоря, этот режим не является проблемой, которую должна решить инфраструктура oAuth. клиентский режим Затем он получает access_token напрямую через ключ и идентификатор клиента и не требует участия пользователя.

войти

Как насчет понимания oAuth2? Протокол oAuth в основном используется для разрешения стороннего входа в систему, но когда речь идет о решениях для входа в различных сценариях, в дополнение к стороннему входу существует еще одна концепция — единый вход.

Единый вход означает, что в нескольких системах пользователю нужно войти в систему только один раз, и каждая система может воспринимать, что пользователь вошел в систему. Например, если вы войдете в Tmall, Taobao также войдет в систему автоматически. Просто поймите, единый вход устроен так: он извлекает логику входа пользователя в двух или более продуктах и ​​может достичь эффекта одновременного входа в несколько продуктов, введя имя пользователя и пароль только один раз.

Реализация единого входа

Первый — это единый вход под одним и тем же родительским доменом, например hr.oa.com, km.oa.com, fuli.oa.com, в этом случае можно установить атрибут домена на домен второго уровня. имя oa.com, чтобы поделиться файлом cookie, а затем сервер может обеспечить единый вход, поделившись сеансом. Помимо обмена сессиями, конечно, это можно реализовать и в JWT.

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

Суммировать

Подводя итог, можно сказать, что для основных решений для входа в систему в различных бизнес-сценариях первым является решение для единого входа для одной и той же компании и одного и того же родительского домена. Атрибут домена включает совместное использование файлов cookie. Затем совместное использование сеансов на стороне сервера может реализовать единый вход. Но есть одно такое решение — JWT. JWT — это веб-токен json. По сути, это строка, состоящая из трех частей: заголовка, полезной нагрузки и подписи.

Второй — это решение для единого входа для одной и той же компании, но в разных доменах, например, для Taobao и единого входа Tmall.Основным решением в этом отношении является CAS.

Третий тип — разные компании, и функция стороннего входа используется для разных доменов. Если стороннему веб-сайту требуется доступ к логину WeChat, логину QQ, логину Weibo и т. д., реализация функции стороннего входа использует только что введенный протокол oAuth2.0.

Справочная статья

Четыре способа OAuth 2.0

Можете обратить внимание на мой паблик-аккаунт «Muchen Classmate», фермера на гусиной фабрике, который обычно записывает какие-то банальные мелочи, технологии, жизнь, инсайты и срастается.