Split documentation to multilingual structure

This commit is contained in:
ErickSkrauch
2019-02-21 03:52:03 +03:00
parent e35de5b5ee
commit b2451ffc9c
15 changed files with 468 additions and 35 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

147
source/ru/api.rst Normal file
View File

@ -0,0 +1,147 @@
Ely.by API (симуляция Mojang API)
---------------------------------
Здесь приведена информация об API, совместимом с функционалом `Mojang Api <http://wiki.vg/Mojang_API>`_. Обращаем ваше
внимание на то, что это не полноценное API Ely.by, а только набор дополнительных запросов, реализованных на базе нашего
`сервера авторизации </minecraft-auth.html>`_.
Заметки
=======
* API не имеет ограничения на количество запросов. У нас есть просто настроенный fail2ban, который будет банить особо
надоедливых клиентов. Такие дела.
Запросы
=======
В этой секции будут описаны запросы и их же варианты для Mojang API. Все запросы выполняются на базовый url
``https://authserver.ely.by``.
UUID по нику на время
~~~~~~~~~~~~~~~~~~~~~
Данный запрос позволяет узнать UUID пользователя по его нику на указанный момент времени. Время задаётся через GET
параметр at с unitx timestamp.
.. note:: На самом деле Ely.by пока не запоминает период смены ника и не обращает внимание на этот запрос. Тем не менее
параметр в будущем будет дореализован.
.. function:: GET /api/users/profiles/minecraft/{username}
Где username - искомый ник пользователя. Он может быть передан в любом регистре (В Mojang API только строгое
совпадение).
Обратите так же внимание, что параметры legacy и demo никогда не будут возвращены, т.к. эти параметры не имеют в Ely
альтернативы и специфичны только для сервисов Mojang.
В случае успешного запроса вы получите следующий ответ сервера:
.. code-block:: javascript
{
"id": "ffc8fdc95824509e8a57c99b940fb996",
"name": "ErickSkrauch"
}
В случае, если переданный ник не будет найден, вы получите ответ с 204 статусом и пустым телом.
Никнейм по UUID + история изменений
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Данный запрос позволяет узнать все ники, использованные пользователем по его UUID.
.. function:: GET /api/user/profiles/{uuid}/names
Где uuid - валиданый UUID. Валидным будет считаться UUID, написанный через дефисы или без них. В случае передачи
невалидной строки, будет возвращён IllegalArgumentException_ с сообщением ``"Invalid uuid format."``.
В случае успешного запроса вы получите следующий ответ сервера:
.. code-block:: javascript
[
{
"name": "Admin"
},
{
"name": "ErickSkrauch",
"changedToAt": 1440707723000
}
]
.. note:: Т.к. на Ely.by не реализован алгоритм запоминания момента смены ника, будет возвращаться только 1 элемент.
Чуть позже мы добавим полноценную поддержку запоминания момента смены ника.
В случае, если переданный UUID не будет найден, вы получите ответ с 204 статусом и пустым телом.
Список никнеймов в их UUID
~~~~~~~~~~~~~~~~~~~~~~~~~~
Этот запрос позволяет запросить список UUID пользователей по списку ников.
.. function:: POST /api/profiles/minecraft
В теле запроса или POST параметрах необходимо передать валидный JSON массив искомых ников.
В массиве должно быть не более 100 ников, в противном случае будет возвращён IllegalArgumentException_ с сообщением
``"Not more that 100 profile name per call is allowed."``. В случае, если переданная строка окажется невалидным
JSON объектом, будет возвращёно это же исключение, только с текстом ``"Passed array of profile names is an invalid
JSON string."``.
Пример тела запроса:
.. code-block:: javascript
["ErickSkrauch", "EnoTiK", "KmotherfuckerF"]
В случае успешного запроса вы получите следующий ответ сервера:
.. code-block:: javascript
[
{
"id": "ffc8fdc95824509e8a57c99b940fb996",
"name": "ErickSkrauch"
},
{
"id": "b8407ae8218658ef96bb0cb3813acdfd",
"name": "EnoTiK"
},
{
"id": "39f42ba723de56d98867eabafc5e8e91",
"name": "KmotherfuckerF"
}
]
Данные возвращаются в том же порядке, в каком и были запрошены.
В случае, если один из переданных никнеймов не найден в базе данных, для него не будет возвращено значения (он будет
просто пропущен). Учитывайте эту ситуацию при парсинге ответа.
Запрос информации о профиле по UUID
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
См. `запрос профиля для сервера авторизации <minecraft-auth.html#profile-request>`_.
Возможные ошибки
================
.. _IllegalArgumentException:
IllegalArgumentException
~~~~~~~~~~~~~~~~~~~~~~~~
Данная ошибка возникает при попытке передать на сервер данные в неправильном формате.
Пример подобной ошибки:
.. code-block:: javascript
// Пример ошибки при неправильном формате UUID
{
"error": "IllegalArgumentException",
"errorMessage": "Invalid uuid format."
}
``errorMessage`` не всегда совпадает с таковым у Mojang, но в основном это касается только специфичных только для Ely
ошибок. Оригинальные же запросы и ожидаемые от них ошибки повторяют тексты Mojang.

View File

@ -0,0 +1,322 @@
Авторизация для Minecraft
-------------------------
Здесь приведена информация по авторизации для лаунчеров и серверов Minecraft через сервис авторизации Ely.by.
Протокол авторизации реализован максимально похожим на `оригинальный протокол авторизации Mojang <http://wiki.vg/Authentication>`_,
но тем не менее эта документация описывает все доступные функции конкретно сервиса авторизации Ely.by.
Общие положения
===============
* Все запросы должны выполняться на URL **https://authserver.ely.by**.
* При успешном запросе, сервер вернёт ответ со статусом 200. Любой другой код свидетельствует об ошибке.
* Сервер всегда отвечает JSON данными, кроме случаев системных ошибок и ответов на legacy запросы. Учитывайте это для
отображения пользователю правильного сообщения об ошибке.
* В случае стандартной ошибки, вы получилите следующие данные:
.. code-block:: javascript
{
"error": "Краткое описание ошибки",
"errorMessage": "Более длинное описание ошибки на английском языке, пригодное для отображения пользователю."
}
Предусмотренные ошибки
~~~~~~~~~~~~~~~~~~~~~~
В отличие от оригинального протокола, на Ely применяется меньший зоопарк ошибок:
.. list-table::
:widths: 20 50 30
:header-rows: 1
* - Ошибка (error)
- Причина
- Решение
* - IllegalArgumentException
- Вы передали неполный список данных для выполнения запроса.
- Внимательно перепроверьте что вы шлёте в запросе и что указано в документации.
* - ForbiddenOperationException
- Пользователь ввёл/разработчик передал неверные значения.
- Необходимо вывести пользователю уведомление о неправильно введённых данных.
Для индикации ошибки Not Found используется ответ с 404 статусом.
Авторизация в лаунчере
======================
В этом разделе описана авторизация для лаунчера или любой другой настольной программы, которой необходимо получить
accessToken для игрового клиента Minecraft. Важно понимать, что этот accessToken не имеет ничего общего с accessToken,
получаемым при oAuth авторизации - это два абсолютно разных ключа.
Все запросы выполняются на подуровень /auth POST запросом.
.. function:: /auth/authenticate
Непосредственная авторизация пользователя, используя его логин (ник или e-mail) и пароль.
Входные параметры:
:username: Никнейм пользователя или его e-mail (более предпочтительно).
:password: Пароль пользователя.
:clientToken: Уникальный токен лаунчера пользователя.
Успешный ответ:
.. code-block:: javascript
{
'accessToken': "Длинная_строка_содержащая_access_token",
'clientToken': ереданный_в_запросе_client_token",
'availableProfiles': {}, /* См. ниже */
'selectedProfile': {
'id': "Длинная_строка_с_uuid_пользователя",
'name': "Текущий_nickname_пользователя",
'legacy': false
}
}
**availableProfiles** содержит в себе массив с одним элементом, таким же, как и selectedProfile. Добавлено только для
соответствия оригинальному протоколу и на деле не используется самими Mojang.
Касательно параметра **legacy** в selectedProfile в оригинальном протоколе явно не даны пояснения на счёт этого
параметра, но сказано, что обычно он в false. Возможно, он как-то используется официальным лаунчером.
.. function:: /auth/refresh
Обновляет валидный accessToken. Этот запрос позволяет не хранить на клиенте его пароль, а оперировать только сохранённым
значением accessToken для практически бесконечной возможности проходить авторизацию.
Входные параметры:
:accessToken: Уникальный ключ, полученый после авторизации.
:clientToken: Уникальный идентификатор клиента, относительно которого получен accessToken.
.. note:: В оригинальном протоколе так же передаётся значение selectedProfile, но на деле от него мало что зависит и
для идентификации пользователя достаточно только этих двух параметров. Наш сервер не обидится, увидив его -
он просто его проигнорирует.
В случае получения какой-либо предусмотренной ошибки, следует заново запросить пароль пользователя и произвести
обычную авторизацию.
Успешный ответ:
.. code-block:: javascript
{
'accessToken': "Новая_длинная_строка_ содержащая_access_token",
'clientToken': ереданный_в_запросе_client_token",
'selectedProfile': {
'id': "Длинная_строка_с_uuid_пользователя",
'name': "Текущий_nickname_пользователя",
'legacy': false
}
}
.. function:: /auth/validate
Этот запрос позволяет проверить валиден ли указанный accessToken или нет. Этот запрос не обновляет токен и его время
жизни, а только позволяет удостовериться, что он ещё действительный. При отправке устаревшего токена, будет выведено
соответствующее сообщение, а сам токен будет удалён из базы.
Входные параметры:
:accessToken: Уникальный ключ, полученый после авторизации.
Успешным ответом будет являться пустое тело. Ориентируйтесь на поле **error** в теле ответа.
.. function:: /auth/signout
Этот запрос позволяет выполнить инвалидацию всех выданных пользователю токенов.
Входные параметры:
:username: Никнейм пользователя или его e-mail (более предпочтительно).
:password: Пароль пользователя.
Успешным ответом будет являться пустое тело. Ориентируйтесь на поле **error** в теле ответа.
.. function:: /auth/invalidate
Запрос позволяет инвалидировать accessToken. В случае, если переданный токен не удастся найти в хранилище токенов,
ошибка не будет сгенерирована и вы получите успешный ответ.
Входные параметры:
:accessToken: Уникальный ключ, полученый после авторизации.
:clientToken: Уникальный идентификатор клиента, относительно которого получен accessToken.
Успешным ответом будет являться пустое тело. Ориентируйтесь на поле **error** в теле ответа.
Авторизация на сервере
======================
Эти запросы выполняются непосредственно клиентом и сервером при помощи внутреннего кода или библиотеки authlib
(начиная с версии 1.7.2). Они актуальны только в том случае, если вы уже произвели авторизацию и запустили игру с валидным
accessToken. Вам остаётся только заменить пути внутри игры/библиотеки на привидённые ниже пути.
Поскольку непосредственно изменить что-либо в работе authlib или игры вы не можете, здесь не приводятся передаваемые значения
и ответы сервера. При необходимости вы сможете найти эту информацию самостоятельно в интернете.
Через authlib
~~~~~~~~~~~~~
.. important:: Эта часть документации описывает запросы, выполняемые через authlib в версии игры 1.7.2+. Для более старых
версий смотрите раздел ниже.
Все запросы из этой категории выполняются на подуровень /session. Перед каждым из запросов указан тип отправляемого запроса.
.. function:: POST /session/join
Запрос на этот URL производится клиентом в момент подключения к серверу с online-mode=true.
.. function:: GET /session/hasJoined
Запрос на этот URL выполняет сервер с online-mode=true после того, как клиент, пытающийся к нему подключится, успешно
выполнит join запрос.
.. attention:: Внутри тела ответа есть параметр **properties**, который, в свою очередь, содержит поле **value** с
закодированной в ней base64 строкой. В оригинальной системе авторизации данные зашифрованы с помощью
приватного ключа и расшифровывались на клиенте с помощью публичного.
Ely, в свою очередь, **не выполняет шифрацию вовсе**, поэтому вам необходимо отключить проверку подписи в
библиотеке authlib. В противном случае текстуры всегда будут признаваться невалидными.
Для старых версий
~~~~~~~~~~~~~~~~~
.. important:: Эта часть документации описывает запросы, выполняемые более старыми версиями Minecraft, когда не применялась
библиотека authlib. Это все версии, младше версии 1.7.2.
Все запросы из этой категории выполняются на подуровень /session/legacy. Перед каждым из запросов указан тип отправляемого запроса.
Принцип обработки этих запросов такой же, как и для authlib, отличие только во входных параметрах и возвращаемых значения.
.. function:: GET /session/legacy/join
Запрос на этот URL производится клиентом в момент подключения к серверу с online-mode=true.
.. function:: GET /session/legacy/hasJoined
Запрос на этот URL выполняет сервер с online-mode=true после того, как клиент, пытающийся к нему подключится, успешно
выполнит join запрос.
Важно не потерять GET параметр **?user=** в конце обоих запросов, чтобы получились следующие URL:
``http://minecraft.ely.by/session/legacy/hasJoined?user=``.
Одиночная игра
==============
По сути, одиночная игра - это локальный сервер, созданный для одного игрока. По крайней мере это так, начиная с версии 1.6,
в которой и был представлен механизм локальных серверов.
Тем не менее, описанный ниже запрос актуален только для Minecraft 1.7.6+, когда для загрузки скинов стала использоваться
так же authlib.
.. _profile-request:
.. function:: GET /session/profile/{uuid}
Запрос на этот URL выполняется клиентом в одиночной игре на локальном сервере (созданном посредством самой игры).
В URL передаётся UUID пользователя, с которым был запущен клиент, а в ответ получается информация о текстурах игрока
в таком же формате, как и при hasJoined запросе.
Готовые библиотеки authlib
==========================
Поскольку самостоятельная реализация связана с трудностями поиска исходников, подключения зависимостей и в конце-концов с
процессом компиляции, ниже приведён список пропатченых библиотек со всеми необходимыми изменениями адресов, отключённой
проверкой подписи и встроенной системой скинов для серверов с online-mode=false. Вы можете использовать их "как есть".
* Minecraft 1.8 - :download:`authlib 1.5.17 <_static/minecraft-auth/authlib/authlib-1.5.17.jar>`
* Minecraft 1.7.10 - :download:`authlib 1.5.16 <_static/minecraft-auth/authlib/authlib-1.5.16.jar>`
* Minecraft 1.7.9 - :download:`authlib 1.5.13 <_static/minecraft-auth/authlib/authlib-1.5.13.jar>`
В более ранних версиях система скинов находилась внутри клиента, так что библиотеки ниже обеспечивают только авторизацию.
* Minecraft 1.7.5 - :download:`authlib 1.3.1 <_static/minecraft-auth/authlib/authlib-1.3.1.jar>`
* Minecraft 1.7.2 - :download:`authlib 1.3 <_static/minecraft-auth/authlib/authlib-1.3.jar>`
.. hint:: На самом деле вам нужен только файл ``YggdrasilMinecraftSessionService.class``. Но здесь приведены готовые
библиотеки, чтобы вам не нужно было его искать и самостоятельно изменять.
Для использования библиотеки вам необходимо заменить оригинальную, располагающуюся по пути /libraries/com/mojang/authlib/
согласно её имени или же положить в другое место и просто при запуске игры подключить её, вместо оригинальной.
Установка authlib на сервер
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Кроме этого библиотеку необходимо установить и на сервер. Для этого вам понадобится файл сервера с расширением .jar.
Щёлкните на нём правой кнопкой мыши, выберите вариант "Открыть с помощью..." и выберите удобный архиватор (скорее всего WinRar).
Затем проделайте те же действия с authlib такой же версии, что и ваш сервер.
Перед вами будет 2 окна: одно с файлами authlib, другое с файлами сервера. Вам необходимо перетащить **только папку "com"**
из authlib на сервер и подтвердить замену.
.. figure:: _static/minecraft-auth/authlib-install.png
:align: center
:alt: Процесс перетягивания: что куда.
После этих действий вы можете закрыть оба окна и в настройках сервера включить online-mode=true, авторизация через Ely.by
установлена и работает!
Установка на версии ниже 1.7.2
==============================
Для более старых версий существует достаточно большое многообразие различных случаев, раскрыть которые в этой документации
не представляется возможным. Вся установка заключается в замене определённых строк в определённых классах через
InClassTranslator.
На форуме RuBukkit есть отличный пост, в котором собрана вся нужна информация по именам классов на различных версиях
Minecraft. Переписывать его сюда не имеет смысла, так что просто перейдите на его страницу и найдите нужную версию.
|rubukkit_link|.
.. |rubukkit_link| raw:: html
<a href="http://www.rubukkit.org/threads/spisok-klassov-i-klientov-dlja-mcp.25108/#post-303710" target="_blank">RuBukkit -
Список классов и клиентов для MCP</a>
Пример установки
~~~~~~~~~~~~~~~~
Предположим, что вы хотите установить авторизацию на сервер версии 1.5.2.
Сначала вы переходите по вышепривидённой ссылке, выбираете нужную версию (1.5.2) и видите список классов:
* **bdk.class** - путь до joinserver
* **jg.class** - путь до checkserver
Затем вы должны взять .jar файл клиента и открыть его любым архиватором. После чего вам необходимо найти файл **bdk.class**.
Для этого удобно воспользоваться поиском.
После того, как вы нашли файл, его нужно извлечь из архива - просто перетащите его оттуда в удобную для вас дирикторию.
Дальше запустите InClassTranslator и в нём откройте этот класс. Слева будет список найденных в файле строк, которые вы
можете изменить. Нужно заменить только строку, отвечающую за запрос на подключение к серверу:
.. figure:: _static/minecraft-auth/installing_by_inclasstranslator.png
:align: center
:alt: Процесс перетягивания: что куда.
После этого вам нужно положить изменённый .class обратно в .jar файл игры.
Ту же самую операцию вам необходимо провести и с сервером, только заменить ссылку на hasJoined.
-----------------------
После этих действий вам нужно в настройках включить online-mode=true и сервер станет пускать на себя только тех игроков,
которые будут авторизованы через Ely.by.

426
source/ru/oauth.rst Normal file
View File

@ -0,0 +1,426 @@
Авторизация по протоколу OAuth2
-------------------------------
На этой странице вы найдёте информацию о реализации авторизации по протоколу OAuth2 на вашем проекте через сервис
Аккаунты Ely.by. Реализация этого протокола позволяет вашим пользователям производить авторизацию с использованием
своего аккаунта Ely.by.
Регистрация приложения
======================
Для начала вам необходимо `создать новое приложение <https://account.ely.by/dev/applications/new>`_. Выберите в качестве
типа приложения **Веб-сайт**. В качестве *адреса переадресации* можно указать только домен, но для повышения
безопасности лучше использовать полный путь переадресации. Примеры допустимых адресов:
* :samp:`http://site.com`
* :samp:`http://site.com/oauth/ely`
* :samp:`http://site.com/oauth.php?provider=ely`
После успешного добавления приложения вы попадёте на страницу со списком всех ваших приложений. Кликнув по названию
приложения вы увидите его идентификатор ``clientId`` и секрет ``clientSecret``. Они буду использоваться на
следующих шагах.
Инициализация авторизации
=========================
Для инициализации процесса авторизации вам необходимо перенаправить пользователя по следующему URL:
.. code-block:: text
https://account.ely.by/oauth2/v1?client_id=<clientId>&redirect_uri=<redirectUri>&response_type=code&scope=<scopesList>
.. list-table:: Допустимые параметры запроса
:widths: 1 1 98
:header-rows: 1
* - Параметр
- Пример значения
- Описание
* - *clientId*
- :samp:`ely`
- **Обязательное**. ClientId, полученный при регистрации.
* - *redirect_uri*
- :samp:`http://site.com/oauth.php`
- **Обязательное**. Адрес обратной переадресации, совпадающий с адресом, указанным при регистрации приложения
* - *response_type*
- :samp:`code`
- **Обязательное**. Тип ответа. На данный момент поддерживается только ``code``.
* - *scope*
- :samp:`account_info account_email`
- **Обязательное**. Перечень разрешений, доступ к которым вы хотите получить, разделённые пробелом. Смотрите все
доступные права в `разделе ниже <#available-scopes>`_.
* - *state*
- :samp:`isfvubuysdboinsbdfvit`
- Случайно сгенерированная строка. Используется для увеличения безопасности в качестве идентификатора сессии. Будет
возвращена в неизменённом виде после завершения авторизации.
* - *description*
- :samp:`यो अनुप्रयोग विवरण`
- Если ваше приложение доступно на нескольких языках, то используя это поле вы можете переопределить стандартное
описание в соответствии с предпочтительным языком пользователя.
* - *prompt*
- :samp:`consent` или :samp:`select_account`
- Принудительно отобразить запрос прав (``consent``) или принудительно запросить выбор аккаунта
(``select_account``).
* - *login_hint*
- :samp:`erickskrauch` или :samp:`erickskrauch@ely.by`
- Если у пользователя есть несколько аккаунтов, то указав этот в этом параметре username или email пользователя вы
автоматически выберете аккаунт за него. Это полезно в случае повторного входа, когда токен истёк.
.. _available_scopes:
.. list-table:: Перечень доступных scopes
:widths: 1 99
:header-rows: 0
* - **account_info**
- Получение информации о пользователе.
* - **account_email**
- В ответе на запрос информации о пользователе будет также присутствовать его email.
* - **offline_access**
- Вместе с ``access_token`` вы также получите и ``refresh_token``. Смотрите подробнее
`соответствующем разделе <#refresh-token-grant>`_.
* - **minecraft_server_session**
- ``access_token`` можно будет использовать в качестве сессии для Minecraft.
------------------------------------------------------------------------------------------------------------------------
Сформировав ссылку, разместите её в вашем шаблоне:
.. code-block:: html
<a href="<ваша_ссылка>">Войти через Ely.by</a>
По нажатию на ссылку, пользователь попадёт на нашу страницу авторизации, откуда после он будет перенаправлен обратно
по адресу, указанному в параметре ``redirect_uri``.
Обратная переадресация выполняется в виде ``<redirect_uri>?code=<код авторизации>&state=<state>`` для успешной
авторизации и ``<redirect_uri?error=<идентификатор ошибки>&error_message=<описание ошибки>`` для неудачной.
Пример успешного и неудачного редиректов:
.. code-block:: text
http://site.com/oauth/ely.php?code=dkpEEVtXBdIcgdQWak4SOPEpTJIvYa8KIq5cW9GJ&state=ajckasdcjasndckbsadc
http://site.com/oauth/ely.php?error=access_denied&error_message=The+resource+owner+or+authorization+server+denied+the+request.
.. _authorization-code-grant:
Обмен кода на ключ
==================
После получения кода авторизации (``auth_code``), вам необходимо обменять его на ключ авторизации (``access_key``).
Для этого необходимо выполнить POST запрос на URL:
.. code-block:: text
https://account.ely.by/api/oauth2/v1/token
И передать туда следующие параметры:
.. list-table::
:widths: 1 99
:header-rows: 0
* - ``client_id``
- ClientID, полученный при регистрации приложения.
* - ``client_secret``
- ClientSecret, полученный при регистрации приложения.
* - ``redirect_uri``
- Точный адрес, использованный для переадресации пользователя.
* - ``grant_type``
- В данном случае указывается ``authorization_code``.
**Пример реализации обмена на PHP:**
.. code-block:: 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);
}
Пояснение к коду:
* Сначала мы объявляем переменную ``$oauthParams``, в которую заносим значения, полученные после регистрации приложения.
* Затем проверяем, не возникла-ли ошибка. В этом случае сразу же прерываем выполнение.
* Формируем POST запрос к форме обмена ``code`` на ``access_token``, передавая необходимые поля.
* Выполняем запрос, получаем ответ, переводим его из JSON в ассоциативный массив.
.. _authorization-code-grant-response:
Ответ сервера
~~~~~~~~~~~~~
В случае успешного запроса в теле ответа будет находиться результат обмена кода авторизации на ``access_token``.
Данные являются JSON документом и могут быть легко интерпретированы средствами используемого языка программирования.
Тело JSON документа содержит следующие поля:
.. code-block:: javascript
{
"access_token": "4qlktsEiwgspKEAotazem0APA99Ee7E6jNryVBrZ",
"refresh_token": "m0APA99Ee7E6jNryVBrZ4qlktsEiwgspKEAotaze", // Представлен только в случае запроса с правами offline_access
"token_type": "Bearer",
"expires_in": 86400 // Количество секунд, на которое выдан токен
}
На этом процедура авторизации закончена. Полученный ``access_token`` может быть использован для получения информации о
пользователе и взаимодействия с нашим API.
Получение информации о пользователе
===================================
Если полученный токен имеет scope ``account_info``, то вы можете запросить информацию об аккаунте пользователя. Для
этого необходимо отправить запрос на URL:
.. code-block:: text
https://account.ely.by/api/account/v1/info
Для передачи ``access_token`` используется заголовок ``Authorization`` со значением ``Bearer {access_token}``.
**Пример реализации получения информации о пользователе на PHP:**
.. code-block:: php
<?php
$accessToken = 'some_access_token_value';
$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_HTTPHEADER, [
'Authorization: Bearer ' . $accessToken,
]);
$result = json_decode(curl_exec($curl), true);
curl_close($curl);
В ответ вы получите JSON документ со следующим содержимым:
.. code-block:: json
{
"id": 1,
"uuid": "ffc8fdc9-5824-509e-8a57-c99b940fb996",
"username": "ErickSkrauch",
"registeredAt": 1470566470,
"profileLink": "http:\/\/ely.by\/u1",
"preferredLanguage": "be",
"email": "erickskrauch@ely.by"
}
Обратите внимание, что поле ``email`` будет присутствовать лишь в том случае, когда был запрошен scope
``account_email``.
.. note:: В ходе дальнейшего развития сервиса, количество возвращаемых полей может увеличиться, но уже существующие
останутся теми же.
.. _refresh-token-grant:
Обновление токена доступа
=========================
Если при выполнении авторизации вами было запрошено право на получение scope ``offline_access``, то вместе с
``access_token`` вы также получите и ``refresh_token``. Данный токен не истекает и может быть использован для получения
нового токена доступа, когда он истечёт.
Для выполнения операции обновления токена необходимо отправить POST запрос на тот же URL, что использовался и
`при обмене кода на ключ доступа <#authorization-code-grant>`_, но со следующими параметрами:
.. list-table::
:widths: 1 99
:header-rows: 0
* - ``client_id``
- ClientID, полученный при регистрации приложения.
* - ``client_secret``
- ClientSecret, полученный при регистрации приложения.
* - ``scope``
- Те же scope, что были запрошены и при получении начального токена доступа. Попытка запросить большее количество
прав приведёт к ошибке.
* - ``refresh_token``
- Непосредственно токен, полученный вместе с начальным токеном доступа.
**Пример реализации обновления токена доступа на PHP:**
.. code-block:: 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);
В качестве ответа будет точно такое же тело, какое было получено в результате
`обмена кода на ключ доступа <#authorization-code-grant-response>`_. Поле ``refresh_token`` будет отсутствовать.
Готовые библиотеки
==================
Более простым способом будет использовать уже готовую библиотеку, которой будет необходимо передать лишь регистрационные
параметры. Ниже перечислены библиотеки для различных языков программирования. Вы можете дополнить этот список своей
библиотекой.
* **PHP**:
- [Official] https://github.com/elyby/league-oauth2-provider
* **Ruby**:
- [Official] https://github.com/elyby/omniauth-ely
Возможные ошибки
================
Ниже приведены стандартные ошибки, которые вы можете получить в случае неправильной передачи данных на сервер
авторизации. Если вы столкнулись с ошибкой, не описанной в этой документации, пожалуйста, сообщите о ней через
`форму обратной связи <http://ely.by/site/contact>`_.
.. _auth-start-errors:
Ошибки при инициализации авторизации
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Этот раздел описывает ошибки, отображаемые при переадресации пользователя с вашего сайта на нашу страницу инициализации
авторизации.
.. code-block:: text
Invalid request ({parameter} required).
Данная ошибка означает, что вы передали не все необходимые параметры. Чтобы решить эту ошибку просто добавьте
недостающий параметр.
.. code-block:: text
Invalid response type '{invalid_response_type_value}'.
Данная ошибка означает, что вы передали неподдерживаемый тип ``response_type``. На данный момент поддерживается только
значение ``code``.
.. code-block:: text
Invalid scope '{invalid_scope}'.
Ошибка указывает на то, что было запрошено неизвестный ``scope``. Убедитесь, что вы запрашиваете
`поддерживаемые права <#available-scopes>`_.
.. code-block:: text
Can not find application you are trying to authorize.
Данная ошибка говорит о том, что переданные параметры не соответствуют ни одному из зарегистрированных приложений.
Для решения проблемы исправьте ваши значения ``client_id`` и ``redirect_uri``.
.. _issue-token-errors:
Ошибки при обмене кода на ключ
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
В случае возникновения ошибки вместо ожидаемого ответа с ``200`` статусом вы получите ``40x`` код и следующие 2 поля:
.. code-block:: 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:**
.. list-table::
:widths: 1 99
:header-rows: 0
* - ``invalid_request``
- Переданы не все необходимые параметры запроса или значение ``code`` не был найден в базе выданных кодов.
* - ``unsupported_grant_type``
- Данная ошибка сигнализирует о том, что вы попытались произвести авторизацию по неизвестному для нашего OAuth2
сервера типу Grant.
* - ``invalid_client``
- Эта ошибка возникает в случае, когда трио значений ``client_id``, ``client_secret`` и ``redirect_uri`` не совпали
ни с одним из зарегистрированных приложений.
Ошибки при запросе информации о пользователе
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Ответ со статусом ``401`` указывает на то, что заголовок ``Authorization`` не присутствует в запросе или его значение
сформировано неверно. Тело ответа будет следующим:
.. code-block:: json
{
"name": "Unauthorized",
"status": 401,
"message": "Your request was made with invalid credentials."
}
Ответ со статусом ``403`` сигнализирует о том, что переданный в заголовке ``Authorization`` токен не содержит scope
``account_info`` или он истёк. Получаемый ответ будет иметь следующий формат:
.. code-block:: json
{
"name": "Forbidden",
"status": 403,
"message": "You are not allowed to perform this action."
}
Ошибки при обновлении токена доступа
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
При выполнении обновления токена доступа вам могут встретиться те же ошибки, что и при
`обмене кода на ключ доступа <#issue-token-errors>`_, а также несколько новых:
.. list-table::
:widths: 1 99
:header-rows: 0
* - ``invalid_request``
- Переданы не все необходимые параметры запроса или значение ``refresh_token`` не был найден в базе выданных
токенов.
* - ``invalid_scope``
- Были перечислены неподдерживаемые scope или запрошено больше, чем было у изначального токена.

163
source/ru/skins-system.rst Normal file
View File

@ -0,0 +1,163 @@
Система скинов
--------------
На этой странице вы найдёте информацию о самостоятельной реализации системы скинов на базе сервиса Ely.by.
Система скинов Ely.by, в отличие от других, не заменяет, а дополняет официальную, тем самым игроки с лицензией не теряют
свои скины, а игроки без лицензии смогут установить себе скин и видеть скины других игроков.
Кроме того, в основных принципах сервиса лежит соответствие официальной системе скинов: нет плащей, нет ушек, нет HD-скинов.
Это означает, что на вашем сервере не будут бегать разноцветные пугала с вырвиглазными скинами.
URL-адреса запросов
===================
Система скинов располагается по URL **http://skinsystem.ely.by**. На сервере доступно 3 основных обработчика:
.. function:: /skins/{nickname}.png
Этот URL отвечает за загрузку скинов. Вместо параметра **nickname** необходимо передать ник игрока. Расширение .png можно опустить.
.. function:: /cloaks/{nickname}.png
Этот URL отвечает за загрузку плащей. Вместо параметра **nickname** необходимо передать ник игрока. Расширение .png можно опустить.
Хотя Ely.by не поддерживает пользовательскую загрузку плащей, мы оставляем за собой право устанавливать дополнительные,
относительно официальной системы скинов, плащи. В любом случае, мы будет пользоваться теми же принципами, что и Mojang -
плащи только за великие заслуги.
.. function:: /textures/{nickname}
По этому URL вы можете получить текстуры для указанного в запросе **nickname**. Результатом является JSON строка, с
meta-информацией о скине следующего формата:
.. code-block:: javascript
{
'SKIN': {
'url': 'http://example.com/skin.png',
'hash': 'uniquehashofskin',
'metadata': {
'model': 'default' /* default или slim, в зависимости от формата скина */
}
},
'CAPE': {
'url': '',
'hash': ''
}
}
*В абсолютном большинстве случаев, содержание CAPE будет именно таким, как показано выше.*
.. note:: Ник не чувствителен к регистру и внутри обработчика в любом случае приводится к нижнему регистру.
Кроме того, для всех запросов необходимо в GET параметрах передать следующие значения:
:version: Версия протокола, по которому идёт запрос на скины. На данный момент таковым является 2 протокол, т.е. вам
нужно всегда указывать version=2.
:minecraft_version: Версия Minecraft, с которой идёт запрос. Этот параметр можно не передавать в том случае, если вы
передаёте параметр authlib_version.
:authlib_version: Версия authlib, с которой выполняется запрос. Этот параметр актуален для версий Minecraft 1.7.6+, когда
для загрузки скинов стала использоваться отдельная библиотека, а не реализация внутри игры.
Параметр может быть передан вместо параметра **minecraft_version**.
Если в запросе не будет параметра **version** и **minecraft_version** или **authlib_version**, сервер ответит 400
ошибкой и скин не будет загружен.
Примеры запросов
~~~~~~~~~~~~~~~~
.. code-block:: text
http://skinsystem.ely.by/skins/erickskrauch.png?version=2&minecraft_version=1.7.2
Получает скин игрока **erickskrauch** с версии Minecraft 1.7.2.
.. code-block:: text
http://skinsystem.ely.by/cloaks/notch?version=2&minecraft_version=1.6.4
Получает плащ игрока **notch** с версии Minecraft 1.6.4. Обратите внимание, что расширение ".png" не передано.
.. code-block:: text
http://skinsystem.ely.by/textures/EnoTiK?version=2&authlib_version=1.5.17
Получает текстуры игрока **EnoTiK** с версии authlib 1.5.17 (версия Minecraft 1.8).
Вспомогательные адреса запросов
===============================
Кроме того, во 2 версии протокола системы скинов определены несколько специальных URL, которые проксируют трафик внутрь
основных запросов, перечисленных выше.
Ник как GET параметр
~~~~~~~~~~~~~~~~~~~~
Эти URL, в отличие от основных запросов, позволяют передать ник игрока в качестве одного из GET параметров. Такие запросы
полезены для версии Minecraft 1.5.2 и ниже, когда внутри кода игры не использовалась подстановка %s для ника, а производилась
простая конкатенация строк. Таким образом можно передать все необходимые GET параметры, указав ник последним.
.. function:: /skins/?name={nickname}.png
Тот же запрос на скин. Вместо параметра **nickname** необходимо передать ник игрока. Расширение .png можно опустить.
.. function:: /cloaks/?name={nickname}.png
Тот же запрос на плащ. Вместо параметра **nickname** необходимо передать ник игрока. Расширение .png можно опустить.
Примеры запросов:
"""""""""""""""""
.. code-block:: text
http://skinsystem.ely.by/skins/?version=2&minecraft_version=1.5.2&name=erickskrauch.png
Получает скин игрока **erickskrauch** с версии Minecraft 1.5.2.
.. code-block:: text
http://skinsystem.ely.by/cloaks/?version=2&minecraft_version=1.4.7&name=notch
Получает плащ игрока **notch** с версии Minecraft 1.4.7. Обратите внимание, что расширение ".png" не передано.
Старый формат запроса
~~~~~~~~~~~~~~~~~~~~~
В 1 версии протокола системы скинов применялся другой способ загрузки скинов. Все запросы шли по URL
**http://ely.by/minecraft.php** и все данные передавались через GET параметры.
На данный момент любой запрос, выполненный на вышеуказанный URL приведёт к 301 редиректу на
**http://skinsystem.ely.by/minecraft.php**, где запрос будет проксирован на основные запросы.
Этот запрос является fallback роутом, применяемым для обратной совместимости с 1 версией и не рекомендуется для
использования в новых проектах. Тем не менее, он должен быть описан, так как применятся и будет достаточно долго применяться
в связи с долгосрочным переходом на 2 версию протокола системы скинов.
1 версия системы скинов (deprecated)
====================================
.. warning:: Информация в этом разделе является устаревшей и приведена здесь только ради создания иллюзии крутого развития
проекта. В любом случае вы **не должны** использовать этот протокол, т.к. в один момент он окончательно перестанет
работать.
На старте проекта применялся URL для загрузки скинов **http://ely.by/minecraft.php**, в который через GET параметры
передавались данные. Сейчас этот URL является устаревшим и планомерно выводится из обращения в пользу 2 версии протокола.
.. function:: /minecraft.php
Параметры, передаваемые в этот запрос:
:name: Имя игрока без учёта регистра и без расширения **.png**.
:type: Тип запрашиваемых данных. Возможные значения: skin и cloack. Изначально была допущена ошибка, из-за которой
запрос на плащи шёл с значением cloack, вместо cloak. Увы, это так и останется в истории проекта.
:mine_ver: Версия Minecraft. Точки в версии должны были быть заменены на прочерки, т.е. 1.7.2 должно было быть передано
как 1_7_2. Хотя могло работать и с точками :)
:ver: Версия протокола. Обычно передавалось значение 1_0_0, которое, в принципе, ни на что не влияло, но тем не менее
передавалось. Сейчас применяется для идентификации запроса, проксируемого с 1 версии во 2.