mirror of
https://github.com/elyby/docs.git
synced 2025-05-31 14:11:48 +05:30
252 lines
22 KiB
Markdown
252 lines
22 KiB
Markdown
# Авторизация по протоколу OAuth2
|
||
На этой странице вы найдёте информацию о реализации авторизации по протоколу OAuth2 на вашем проекте через сервис Аккаунты Ely.by. Реализация этого протокола позволяет вашим пользователям производить авторизацию с использованием своего аккаунта Ely.by.
|
||
|
||
## Регистрация приложения {#app-registration}
|
||
Для начала вам необходимо создать новое приложение. Выберите тип приложения Веб‑сайт. В качестве *адреса переадресации* можно указать только домен, но для повышения безопасности лучше использовать полный путь переадресации. Примеры допустимых адресов:
|
||
* `https://example.com`
|
||
* `https://example.com/oauth/ely`
|
||
* `https://example.com/oauth.php?provider=ely`
|
||
|
||
После успешного добавления приложения вы попадёте на страницу со списком всех ваших приложений. Кликнув по названию приложения вы увидите его идентификатор `clientId` и секрет `clientSecret`. Они буду использоваться на следующих шагах.
|
||
|
||
## Инициализация авторизации {#auth-init}
|
||
Для инициализации процесса авторизации вам необходимо перенаправить пользователя по следующему URL:
|
||
```url
|
||
https://account.ely.by/oauth2/v1?client_id=<clientId>&redirect_uri=<redirectUri>&response_type=code&scope=<scopesList>
|
||
```
|
||
|
||
Сформировав ссылку, разместите её в вашем шаблоне:
|
||
```html
|
||
<a href="<ваша_ссылка>">Войти через Ely.by</a>
|
||
```
|
||
По нажатию на ссылку, пользователь попадёт на нашу страницу авторизации, откуда после он будет перенаправлен обратно по адресу, указанному в параметре redirect_uri.
|
||
|
||
Обратная переадресация выполняется в виде `<redirect_uri>?code=<код авторизации>&state=<state>` для успешной авторизации и `<redirect_uri>?error=<идентификатор ошибки>&error_message=<описание ошибки>` для неудачной.
|
||
|
||
Пример успешного и неудачного редиректов:
|
||
```url
|
||
https://example.com/oauth/ely.php?code=dkpEEVtXBdIcgdQWak4SOPEpTJIvYa8KIq5cW9GJ&state=ajckasdcjasndckbsadc
|
||
https://example.com/oauth/ely.php?error=access_denied&error_message=The+resource+owner+or+authorization+server+denied+the+request.
|
||
```
|
||
|
||
### Допустимые параметры запроса {#auth-init-params}
|
||
| **Параметр** | **Пример значения** | **Описание** |
|
||
|--------------------|-----------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||
| *clientId* | `ely` | **Обязательное**. ClientId, полученный при регистрации. |
|
||
| *redirect_uri* | `http://site.com/oauth.php` | **Обязательное**. Адрес обратной переадресации, совпадающий с адресом, указанным при регистрации приложения. |
|
||
| *response_type* | `code` | **Обязательное**. Тип ответа. На данный момент поддерживается только `code`. |
|
||
| *scope* | `account_info account_email` | **Обязательное**. Перечень разрешений, доступ к которым вы хотите получить, разделённые пробелом. Смотрите все доступные права в [разделе ниже](#available-scopes). |
|
||
| *state* | `isfvubuysdboinsbdfvit` | Случайно сгенерированная строка. Используется для увеличения безопасности в качестве идентификатора сессии. Будет возвращена в неизменённом виде после завершения авторизации. |
|
||
| *description* | `यो अनुप्रयोग विवरण` | Если ваше приложение доступно на нескольких языках, то используя это поле вы можете переопределить стандартное описание в соответствии с предпочтительным языком пользователя. |
|
||
| *prompt* | `consent` или `select_account` | Принудительно отобразить запрос прав (`consent`) или принудительно запросить выбор аккаунта (`select_account`). |
|
||
| *login_hint* | `erickskrauch` или `erickskrauch@ely.by` | Если у пользователя есть несколько аккаунтов, то указав в этом параметре username или E-mail пользователя, вы автоматически выберете аккаунт за него. Это полезно в случае повторного входа, когда токен истёк. |
|
||
|
||
### Перечень доступных scopes {#available-scopes}
|
||
|
||
| **Scope** | **Описание** |
|
||
|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||
| **account_info** | Получение информации о пользователе. |
|
||
| **account_email** | В ответе на запрос информации о пользователе будет также присутствовать его email. |
|
||
| **offline_access** | Вместе с `access_token` вы также получите и `refresh_token`. Смотрите подробнее в [соответствующем разделе](#refresh-token). |
|
||
| **minecraft_server_session** | `access_token` можно будет использовать в качестве сессии для Minecraft. |
|
||
|
||
## Обмен кода на ключ {#access_key}
|
||
После получения кода авторизации (`auth_code`), вам необходимо обменять его на ключ авторизации (`access_key`). Для этого необходимо выполнить POST запрос на URL:
|
||
```url
|
||
https://account.ely.by/api/oauth2/v1/token
|
||
```
|
||
И передать туда следующие параметры:
|
||
* **client_id**: ClientID, полученный при регистрации приложения.
|
||
* **client_secret**: ClientSecret, полученный при регистрации приложения.
|
||
* **redirect_uri**: Точный адрес, использованный для переадресации пользователя.
|
||
* **grant_type**: В данном случае указывается authorization_code.
|
||
* **code**: Код авторизации, полученный в GET-параметрах после успешной переадресации.
|
||
|
||
```php title="Пример реализации обмена на PHP"
|
||
<?php
|
||
// В этой переменной будут храниться ваши параметры OAuth2.
|
||
$oauthParams = [
|
||
'client_id' => 'ely', // Ваш ClientId, полученный при регистрации.
|
||
'client_secret' => 'Pk4uCtZw5WVlSUpvteJuTZkVqHXZ6aNtTaLPXa7X', // Ваш ClientSecret, полученный при регистрации
|
||
'redirect_uri' => 'http://someresource.by/oauth/some.php', // Адрес, на который вы ожидаете получить пользователя обратно (текущий url).
|
||
'grant_type' => 'authorization_code',
|
||
];
|
||
|
||
// Если возникла ошибка, то прерываем выполнение скрипта.
|
||
if (isset($_GET['error'])) {
|
||
echo $_GET['error_message'];
|
||
return;
|
||
}
|
||
|
||
// Выполняем код ниже только если пришёл код авторизации.
|
||
if (!is_null($_GET['code'])) {
|
||
$oauthParams['code'] = $_GET['code'];
|
||
|
||
$curl = curl_init();
|
||
curl_setopt($curl, CURLOPT_URL, 'https://account.ely.by/api/oauth2/v1/token');
|
||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||
curl_setopt($curl, CURLOPT_POST, true);
|
||
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($oauthParams));
|
||
$out = json_decode(curl_exec($curl), true);
|
||
curl_close($curl);
|
||
}
|
||
```
|
||
:::info[Пояснения к коду]
|
||
Сначала мы объявляем переменную `$oauthParams`, в которую заносим значения, полученные после регистрации приложения.
|
||
Затем проверяем, не возникла-ли ошибка. В этом случае сразу же прерываем выполнение.
|
||
Формируем POST запрос к форме обмена `code` на `access_token`, передавая необходимые поля.
|
||
Выполняем запрос, получаем ответ, переводим его из JSON в ассоциативный массив.
|
||
:::
|
||
|
||
### Ответ сервера {#access_key_result}
|
||
В случае успешного запроса в теле ответа будет находиться результат обмена кода авторизации на `access_token`. Данные являются JSON документом и могут быть легко интерпретированы средствами используемого языка программирования.
|
||
Тело JSON документа содержит следующие поля:
|
||
```json
|
||
{
|
||
"access_token": "4qlktsEiwgspKEAotazem0APA99Ee7E6jNryVBrZ",
|
||
"refresh_token": "m0APA99Ee7E6jNryVBrZ4qlktsEiwgspKEAotaze", // Представлен только в случае запроса с правами offline_access
|
||
"token_type": "Bearer",
|
||
"expires_in": 86400 // Количество секунд, на которое выдан токен
|
||
}
|
||
```
|
||
На этом процедура авторизации закончена. Полученный `access_token` может быть использован для получения информации о пользователе и взаимодействия с нашим API.
|
||
|
||
## Получение информации о пользователе {#get-user-info}
|
||
Если полученный токен имеет scope `account_info`, то вы можете запросить информацию об аккаунте пользователя. Для этого необходимо отправить запрос на URL:
|
||
```url
|
||
https://account.ely.by/api/account/v1/info
|
||
```
|
||
Для передачи `access_token` используется заголовок `Authorization` со значением `Bearer {access_token}`.
|
||
|
||
```php title="Пример реализации получения информации о пользователе на PHP"
|
||
<?php
|
||
$accessToken = 'some_access_token_value';
|
||
|
||
$curl = curl_init();
|
||
curl_setopt($curl, CURLOPT_URL, 'https://account.ely.by/api/account/v1/info');
|
||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||
curl_setopt($curl, CURLOPT_HTTPHEADER, [
|
||
'Authorization: Bearer ' . $accessToken,
|
||
]);
|
||
$result = json_decode(curl_exec($curl), true);
|
||
curl_close($curl);
|
||
```
|
||
В ответ вы получите JSON документ со следующим содержимым:
|
||
```json
|
||
{
|
||
"id": 1,
|
||
"uuid": "ffc8fdc9-5824-509e-8a57-c99b940fb996",
|
||
"username": "ErickSkrauch",
|
||
"registeredAt": 1470566470,
|
||
"profileLink": "http:\/\/ely.by\/u1",
|
||
"preferredLanguage": "be",
|
||
"email": "erickskrauch@ely.by"
|
||
}
|
||
```
|
||
|
||
## Обновление токена доступа {#refresh-token}
|
||
Если при выполнении авторизации вами было запрошено право на получение scope `offline_access`, то вместе с `access_token` вы также получите и `refresh_token`. Данный токен не истекает и может быть использован для получения нового токена доступа, когда он истечёт.
|
||
|
||
Для выполнения операции обновления токена необходимо отправить **POST** запрос на тот же URL, что использовался и при обмене кода на ключ доступа, но со следующими параметрами:
|
||
| **Параметр** | **Описание** |
|
||
|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------|
|
||
| `client_id` | ClientID, полученный при регистрации приложения. |
|
||
| `client_secret` | ClientSecret, полученный при регистрации приложения. |
|
||
| `scope` | Те же scope, что были запрошены и при получении начального токена доступа. Попытка запросить большее количество прав приведёт к ошибке. |
|
||
| `refresh_token` | Непосредственно токен, полученный вместе с начальным токеном доступа. |
|
||
|
||
```php title="Пример реализации обновления токена доступа на PHP"
|
||
<?php
|
||
// refresh_token, полученный при завершении авторизации
|
||
$refreshToken = 'm0APA99Ee7E6jNryVBrZ4qlktsEiwgspKEAotaze';
|
||
|
||
$requestParams = [
|
||
'client_id' => 'ely', // Ваш ClientId, полученный при регистрации
|
||
'client_secret' => 'Pk4uCtZw5WVlSUpvteJuTZkVqHXZ6aNtTaLPXa7X', // Ваш ClientSecret, полученный при регистрации
|
||
'scope' => 'account_info account_email',
|
||
'refresh_token' => $refreshToken,
|
||
'grant_type' => 'refresh_token',
|
||
];
|
||
|
||
$curl = curl_init();
|
||
curl_setopt($curl, CURLOPT_URL, 'https://account.ely.by/api/oauth2/v1/token');
|
||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||
curl_setopt($curl, CURLOPT_POST, true);
|
||
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($requestParams));
|
||
$result = json_decode(curl_exec($curl), true);
|
||
curl_close($curl);
|
||
```
|
||
В качестве ответа будет точно такое же тело, какое было получено в результате [обмена кода на ключ доступа](#access_key_result). Поле `refresh_token` будет отсутствовать.
|
||
|
||
## Готовые библиотеки {#libraries}
|
||
Более простым способом будет использовать уже готовую библиотеку, которой будет необходимо передать лишь регистрационные параметры. Ниже перечислены библиотеки для различных языков программирования. Вы можете дополнить этот список своей библиотекой.
|
||
* **PHP**:
|
||
* [Официальная] https://github.com/elyby/league-oauth2-provider
|
||
* **Ruby**:
|
||
* [Официальная] https://github.com/elyby/omniauth-ely
|
||
|
||
## Возможные ошибки {#errors}
|
||
Ниже приведены стандартные ошибки, которые вы можете получить в случае неправильной передачи данных на сервер авторизации. Если вы столкнулись с ошибкой, не описанной в этой документации, пожалуйста, сообщите о ней через [форму обратной связи](https://ely.by/site/contact).
|
||
|
||
### Ошибки при инициализации авторизации {#errors-init-auth}
|
||
Этот раздел описывает ошибки, отображаемые при переадресации пользователя с вашего сайта на нашу страницу инициализации авторизации.
|
||
|
||
```
|
||
Invalid request ({parameter} required).
|
||
```
|
||
Данная ошибка означает, что вы передали не все необходимые параметры. Чтобы решить эту ошибку просто добавьте недостающий параметр.
|
||
|
||
```
|
||
Invalid response type '{invalid_response_type_value}'.
|
||
```
|
||
Данная ошибка означает, что вы передали неподдерживаемый тип `response_type`. На данный момент поддерживается только значение `code`.
|
||
|
||
```
|
||
Invalid scope '{invalid_scope}'.
|
||
```
|
||
Ошибка указывает на то, что было запрошено неизвестный `scope`. Убедитесь, что вы запрашиваете [поддерживаемые права](#available-scopes).
|
||
|
||
```
|
||
Can not find application you are trying to authorize.
|
||
```
|
||
Данная ошибка говорит о том, что переданные параметры не соответствуют ни одному из зарегистрированных приложений. Для решения проблемы исправьте ваши значения `client_id` и `redirect_uri`.
|
||
|
||
### Ошибки при обмене кода на ключ {#issue-token-errors}
|
||
В случае возникновения ошибки вместо ожидаемого ответа с `200` статусом вы получите `40x` код и следующие 2 поля:
|
||
```json
|
||
{
|
||
"error": "invalid_request",
|
||
"error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Check the \"code\" parameter."
|
||
}
|
||
```
|
||
В поле `error` находится системный идентификатор ошибки, в `error_description` — описание ошибки на английском языке.
|
||
|
||
#### Возможные значения error
|
||
* `invalid_request`: Переданы не все необходимые параметры запроса или значение `code` не было найдено в базе выданных кодов.
|
||
* `unsupported_grant_type`: Данная ошибка сигнализирует о том, что вы попытались произвести авторизацию по неизвестному для нашего OAuth2 сервера типу Grant.
|
||
* `invalid_client`: Эта ошибка возникает в случае, когда трио значений `client_id`, `client_secret` и `redirect_uri` не совпали ни с одним из зарегистрированных приложений.
|
||
|
||
### Ошибки при запросе информации о пользователе {#errors-request-user}
|
||
Ответ со статусом `401` указывает на то, что заголовок `Authorization` не присутствует в запросе или его значение сформировано неверно. Тело ответа будет следующим:
|
||
```json
|
||
{
|
||
"name": "Unauthorized",
|
||
"status": 401,
|
||
"message": "Your request was made with invalid credentials."
|
||
}
|
||
```
|
||
|
||
Ответ со статусом `403` сигнализирует о том, что переданный в заголовке `Authorization` токен не содержит scope `account_info` или он истёк. Получаемый ответ будет иметь следующий формат:
|
||
```json
|
||
{
|
||
"name": "Forbidden",
|
||
"status": 403,
|
||
"message": "You are not allowed to perform this action."
|
||
}
|
||
```
|
||
|
||
### Ошибки при обновлении токена доступа {#errors-renewing-token}
|
||
При выполнении обновления токена доступа вам могут встретиться те же ошибки, что и при [обмене кода на ключ доступа](#issue-token-errors), а также несколько новых:
|
||
* `invalid_request`: Переданы не все необходимые параметры запроса или значение `refresh_token` не был найден в базе выданных токенов.
|
||
* `invalid_scope`: Были перечислены неподдерживаемые scope или запрошено больше, чем было у изначального токена.
|