OAuth - это открытый протокол авторизации, который позволяет потребительским приложениям на веб-платформах, таких как Twitter, GitHub или других, получать доступ к ресурсам владельца ресурса. Рабочая группа IETF OAuth разработала протокол OAuth 2.0 в 2012 году.

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

Платформа OAuth 2.0 определяет несколько типов грантов для разных случаев использования, а также структуру для создания новых типов грантов. В OAuth 2.0 термин «тип предоставления» относится к способу получения приложением токена доступа.

Основные типы грантов для OAuth 2.0 перечислены ниже:

  • Код авторизации
  • Пароль
  • Учетные данные клиента
  • Обновить токен

Структура таблицы

users
| Column                  | Data Type
|----------               |-------------
| id                      | int
| name                    | string
| username                | string
| password                | string
client
| Column                  | Data Type
|----------               |-------------
| id                      | int
| client_id               | string
| client_secret           | string
| name                    | string
| home_page_url           | string
| logo_url                | string
| privacy_policy_url      | string
| user_id                 | string
| is_live                 | bool
| redirect_uri            | []string
client_access_tokens
| Column                  | Data Type
|----------               |-------------
| id                      | int
| client_id               | int
| user_id                 | int
| client_refresh_token_id | int
| access_token            | string
| grant_type              | string
| scope                   | string
| audience                | string
| expired_at              | datetime

client_refresh_tokens
| Column                  | Data Type
|----------               |-------------
| id                      | int
| client_id               | int
| user_id                 | int
| refresh_token           | string
| grant_type              | string
| scope                   | string
| audience                | string
| expired_at              | datetime

client_authorization_codes
| Column                  | Data Type
|----------               |-------------
| id                      | int
| client_id               | int
| user_id                 | int
| code                    | string
| scope                   | []string
| is_used                 | bool
| redirect_uri            | string
| expired_at              | datetime

Предоставление учетных данных клиента

Клиент должен пройти аутентификацию для этого запроса. Обычно служба позволяет принимать идентификатор клиента и секрет в заголовке HTTP Basic auth.

Запрос

POST /oauth/token
Host: authorization-server.com

// header
Authorization: Basic base64_encode(client_id:client_secret) // required

// body
{
  grant_type: "client_credentials", // required
  scope: "get_user_profile" // optional, but if not passed will give full access of the client user
}

Ответ

// body
{
   tokenType: "Bearer",
   expiresIn: 3600,
   accessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
   refreshToken: "eqweasdasdanvbSifkLImUAtuXITjxKMzkXjZvKGGIcLyFqHIDrVNexjHwXBNRhgicutwNStdasdasdLmMjfggjHrYvzWaIANmUvNOoDtNIOKOFywqedsa",
   scope: "get_user_profile"
}

Предоставление пароля

Если клиенту был выдан секрет, то клиент должен аутентифицировать этот запрос. Обычно служба позволяет принимать идентификатор клиента и секрет в заголовке HTTP Basic auth.

Запрос

POST /oauth/token
Host: authorization-server.com

// header
Authorization: Basic base64_encode(client_id:client_secret) // optional

// body
{
  grant_type: "password", // required
  username: "yussuf", // required
  password: "123456" // required
  scope: "get_user_profile" // optional, but if not passed will give full access of the user
}

Ответ

// body
{
   tokenType: "Bearer",
   expiresIn: 3600,
   accessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
   refreshToken: "eqweasdasdanvbSifkLImUAtuXITjxKMzkXjZvKGGIcLyFqHIDrVNexjHwXBNRhgicutwNStdasdasdLmMjfggjHrYvzWaIANmUvNOoDtNIOKOFywqedsa",
   scope: "get_user_profile"
}

Предоставление кода авторизации

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

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

URL-адрес авторизации обычно имеет следующий формат:

https://authorization-server.com/oauth/authorize?client_id=abcdefgh&response_type=code&state=testing&redirect_uri=https%3A%2F%2Ftesting.com%0A&scope=get_user_profile

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

https://testing.com?code=abc123&state=testing

Запрос

POST /oauth/token
Host: authorization-server.com

// header
Authorization: Basic base64_encode(client_id:client_secret) // required

// body
{
  grant_type: "authorization_code", // required
  code: "abc123", // required get from the redirect url code query string
  redirect_uri: "https://testing.com" // required
}

Ответ

// body
{
   tokenType: "Bearer",
   expiresIn: 3600,
   accessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
   refreshToken: "eqweasdasdanvbSifkLImUAtuXITjxKMzkXjZvKGGIcLyFqHIDrVNexjHwXBNRhgicutwNStdasdasdLmMjfggjHrYvzWaIANmUvNOoDtNIOKOFywqedsa",
   scope: "get_user_profile"
}

Обновить грант токена

Если клиенту был выдан секрет, то клиент должен аутентифицировать этот запрос. Обычно служба позволяет принимать идентификатор клиента и секрет в заголовке HTTP Basic auth.

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

Запрос

POST /oauth/token
Host: authorization-server.com

// header
Authorization: Basic base64_encode(client_id:client_secret) // optional

// body
{
  grant_type: "refresh_token", // required
  refresh_token: "eqweasdasdanvbSifkLImUAtuXITjxKMzkXjZvKGGIcLyFqHIDrVNexjHwXBNRhgicutwNStdasdasdLmMjfggjHrYvzWaIANmUvNOoDtNIOKOFywqedsa", // required
  scope: "get_user_profile" // optional, the requested scope must not include additional scopes that were not issued in the original access token, can omit some scope from the original access token.
}

Ответ

// body
{
   tokenType: "Bearer",
   expiresIn: 3600,
   accessToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cnewtoken",
   refreshToken: "eqweasdasdanvbSifkLImUAtuXITjxKMzkXjZvKGGIcLyFqHIDrVNexjHwXBNRhgicutwNStdasdasdLmMjfggjHrYvzWaIANmUvNOoDtNIOKOFywqedsanewrefreshtoken",
   scope: "get_user_profile"
}

Заключение

У каждой компании своя реализация собственного стандарта OAuth, но эта статья основана на платформе авторизации OAuth 2.0 (RFC6749), выпущенной рабочей группой IETF OAuth.

Ссылка

Https://www.oauth.com/

Https://tools.ietf.org/html/rfc6749