started docs migration to docusaurus

This commit is contained in:
McModder
2025-02-05 16:49:22 +03:00
parent 64fdb01e11
commit ea1227cdf9
59 changed files with 20257 additions and 3323 deletions

107
docs/api.md Normal file
View File

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

58
docs/authlib-injector.md Normal file
View File

@@ -0,0 +1,58 @@
# Authlib-Injector
**authlib-injector** — это библиотека, позволяющая подменить адреса серверов авторизации и сессии в Authlib, не модифицируя непосредственно саму библиотеку. Выполнена как javaagent.
Данная библиотека значительно упрощает установку альтернативных сервисов авторизации в игровой клиент и сервер, поскольку она универсально применяет трансформацию в процессе работы программы.
Скачать последнюю версию можно со [страницы релизов на GitHub](https://github.com/yushijinhun/authlib-injector/releases/latest).
Здесь приведена документация к ключевым аспектам установки и использования библиотеки. Для более подробной информации обратитесь к [оригинальной документации на китайском языке](https://github.com/yushijinhun/authlib-injector/wiki).
## Установка в игровой клиент {#client}
:::warning
Обратите внимание, что этот раздел описывает установку **authlib-injector** в игру. Игровой лаунчер по-прежнему должен самостоятельно реализовать процесс авторизации, чтобы после передать `accessToken` в игру.
:::
Для применения библиотеки, необходимо указать её в качестве javaagent для игры. Сделать это можно, добавив в начало команды запуска игры строку `-javaagent:/путь/до/файла/authlib-injector.jar=ely.by`. В результате изменений строка запуска игры должна выглядеть следующим образом:
```bash
java -javaagent:/путь/к/файлу/authlib-injector.jar=ely.by -jar minecraft.jar
```
Если вы запускаете игру через лаунчер, то в его настройках необходимо найти поле для указания дополнительных аргументов JVM, куда необходимо в самое начало вставить строку, приведённую выше.
![Лаунчер Minecraft с окном настроек и аргументом -javaagent... в поле аргументов JVM](/img/launcher-jvm-options.png)
## Установка на сервер {#server}
Также как и в случае с игровым клиентом, библиотеку необходимо указать в качестве javaagent. [Скачайте библиотеку](https://github.com/yushijinhun/authlib-injector/releases/latest) и поместите её в директорию с сервером. После этого добавьте вызов javaagent в команду запуска сервера:
```bash
# До
java -jar minecraft_server.jar
# После
java -javaagent:authlib-injector.jar=ely.by -jar minecraft_server.jar
```
При запуске сервера вы должны увидеть сообщение об активации authlib-injector:
![Authlib-injector log strings at the server startup](/img/server-startup-messages.png)
### BungeeCord {#bungeecord}
authlib-injector должен быть установлен непосредственно на сам BungeeCord, а также **на все сервера** позади него. Обратите внимание на конфигурацию параметра onlinemode:
* В конфигурации BungeeCord (`config.yml`) должно стоять значение `online_mode=true`.
* В конфигурации всех серверов позади прокси (`server.properties`) должно быть указано значение `online-mode=false`.
Благодаря такой конфигурации установки, авторизация будет работать для всех входящих игроков, а на внутренних серверах будут корректно отображаться скины игроков.
### LaunchHelper {#launchhelper}
Не все игровые хостинги позволяют напрямую модифицировать аргументы, с которыми запускается сервер. Чтобы обойти это ограничение, можно использовать специальный сервер, который запускает игровой сервер, подмешивая туда authlib-injector. Для установки следуйте инструкции:
1. Скачайте версию LaunchHelper для вашей операционной системы со [страницы загрузок](https://github.com/Codex-in-somnio/LaunchHelper/releases/latest).
1. Загрузите скачанный файл и файл `authlib-injector.jar` в папку сервера на вашем хостинге.
1. Там же создайте файл `launchhelper.properties` и поместите в него следующее содержимое:
```properties
javaAgentJarPath=authlib-injector.jar
javaAgentOptions=ely.by
execJarPath=minecraft_server.jar
```
Где `javaAgentJarPath` содержит путь до файла `authlib-injector.jar`, а `execJarPath` содержит имя файла сервера.
1. В панели управления хостингом укажите `LaunchHelper.jar` в качестве запускаемого файла сервера.
Если возможности указать исполнимый файл явно нет, то следует переименовать файл `LaunchHelper.jar` в соответствие с требованиями вашего хостинга (обычно, это `server.jar`). В этом случае у вас должна получиться следующая структура файлов:
* `server.jar` - файл LaunchHelper.
* `minecraft_server.jar` - предпочитаемое ядро сервера.
* `authlib-injector.jar` - файл authlib-injector.
* `launchhelper.properties` - файл конфигурации для LaunchHelper.

9
docs/intro.md Normal file
View File

@@ -0,0 +1,9 @@
---
slug: /
sidebar_position: 1
---
# Добро пожаловать в документацию Ely.by! {#welcome}
В этой документации вы найдете информацию о публичных сервисах проекта Ely.by, используя которую вы сможете интегрировать свои проекты с сервисами Ely.by
Вы всегда можете помочь нам улучшить эту документацию

317
docs/minecraft-auth.mdx Normal file
View File

@@ -0,0 +1,317 @@
# Авторизация для Minecraft {#minecraft}
Здесь приведена информация по авторизации для лаунчеров и серверов Minecraft через сервис авторизации Ely.by.
Протокол авторизации реализован максимально похожим на [оригинальный протокол авторизации Mojang](http://wiki.vg/Authentication), но тем не менее эта документация описывает все доступные функции конкретно сервиса авторизации Ely.by.
## Общие положения {#definitions}
* Все запросы должны выполняться на URL `https://authserver.ely.by`.
* При успешном запросе, сервер вернёт ответ со статусом `200`. Любой другой код свидетельствует об ошибке.
* Сервер всегда отвечает JSON данными, кроме случаев системных ошибок и ответов на legacy запросы. Учитывайте это для отображения пользователю правильного сообщения об ошибке.
* В случае стандартной ошибки, вы получите следующие данные:
```json
{
"error": "Краткое описание ошибки",
"errorMessage": "Более длинное описание ошибки на английском языке, пригодное для отображения пользователю."
}
```
### Предусмотренные ошибки {#errors}
В отличие от оригинального протокола, на Ely применяется меньший зоопарк ошибок:
#### IllegalArgumentException
**Причина**: Вы передали неполный список данных для выполнения запроса.
**Решение**: Внимательно перепроверьте что вы шлёте в запросе и что указано в документации.
#### ForbiddenOperationException
**Причина**: Пользователь ввёл/разработчик передал неверные значения.
**Решение**: Необходимо вывести пользователю уведомление о неправильно введённых данных.
{#not-found}Для индикации ошибки **Not Found** используется ответ с `404` статусом
## Авторизация в лаунчере {#launcher}
В этом разделе описана авторизация для игрового лаунчера и описывает действия, необходимые для получения `accessToken` для игрового клиента Minecraft. В результате авторизации будет получен **JWT-токен** с [правами доступа](./oauth.md#available-scopes) `minecraft_server_session`.
:::warning
Мы рекомендуем использовать [протокол авторизации OAuth 2.0](./oauth.md) с запросом [прав доступа](./oauth.md#available-scopes) `minecraft_server_session`, как **более безопасный и удобный** для пользователя метод.
:::
### Авторизация пользователя {#auth-authenticate}
Непосредственная авторизация пользователя, используя его логин (ник или Email), пароль и токен двухфакторной аутентификации.
> **POST /auth/authenticate**
>
> **Параметры**:
> * **username** (*string*) Никнейм пользователя или его Email (более предпочтительно).
> * **password** (*string*) Пароль пользователя или комбинация `пароль:токен`.
> * **clientToken** (*string*) Уникальный токен лаунчера пользователя.
> * **requestUser** (*bool*) Если поле передано как `true`, то в ответе сервера будет присутствовать поле `user`.
Система аккаунтов Ely.by поддерживает защиту пользователей посредством двухфакторной аутентификации. В оригинальном протоколе авторизации Mojang не предусмотрено возможности для передачи TOTP-токенов. Для решения этой проблемы и сохранения совместимости с реализацией сервера [Yggdrasil](https://minecraft.wiki/w/Yggdrasil), мы предлагаем передавать токен в поле `password` в формате `пароль:токен`.
К сожалению, не все пользователи осведомлены об этой возможности, поэтому будет лучше при получении ошибки о защищённости аккаунта пользователя двухфакторной аутентификацией явно запросить у него токен и склеить его программно.
Логика следующая:
1. Если пользователь указал верные логин и пароль, но для его аккаунта включена двухфакторная аутентификация, вы получите ответ с `401` статусом и следующим содержимым:
```json
{
"error": "ForbiddenOperationException",
"errorMessage": "Account protected with two factor auth."
}
```
2. При получении этой ошибки, необходимо запросить у пользователя ввод **TOTPтокена**, после чего повторить запрос на авторизацию с теми же учётными данными, добавив к паролю постфикс в виде `:токен`, где `токен` — это значение, введённое пользователем.
Если пароль пользователя был `password123`, а токен `123456`, то после склейки поле `password` примет значение `password123:123456`.
3. Если в результате этих действий вы получите ответ с `401` статутом и `errorMessage` «Invalid credentials. Invalid email or password.», то это будет свидетельствовать о том, что переданный токен неверен и его нужно перезапросить у пользователя.
Если все данные будут переданы верно, вы получите следующий ответ:
```json
{
"accessToken": "Длинная_строка_содержащая_access_token",
"clientToken": "Переданный_в_запросе_client_token",
"availableProfiles": [
{
"id": "UUID_пользователя_без_дефисов",
"name": "Текущий_username_пользователя"
}
],
"selectedProfile": {
"id": "UUID_пользователя_без_дефисов",
"name": "Текущий_username_пользователя"
},
"user": { /* Только если передан параметр requestUser */
"id": "UUID_пользователя_без_дефисов",
"username": "Текущий_username_пользователя",
"properties": [
{
"name": "preferredLanguage",
"value": "ru"
}
]
}
}
```
### Обновление токена {#auth-refresh}
Обновляет валидный `accessToken`. Этот запрос позволяет не хранить на клиенте его пароль, а оперировать только сохранённым значением `accessToken` для практически бесконечной возможности проходить авторизацию.
> **POST /auth/refresh**
>
> **Параметры**:
> * **accessToken** (*string*) Уникальный ключ, полученный после авторизации.
> * **clientToken** (*string*) Уникальный идентификатор клиента, относительно которого получен accessToken.
> * **requestUser** (*bool*) Если поле передано как `true`, то в ответе сервера будет присутствовать поле `user`.
::note
В оригинальном протоколе так же передаётся значение `selectedProfile`, но в реализации Mojang он не влияет ни на что. Наша реализация сервера авторизации игнорирует этот параметр и опирается на значения `accessToken` и `clientToken`.
:::
В случае получения какой-либо предусмотренной ошибки, следует заново запросить пароль пользователя и произвести обычную авторизацию.
Успешный ответ:
```json
{
"accessToken": "Новая_длинная_строка_ содержащая_access_token",
"clientToken": "Переданный_в_запросе_client_token",
"selectedProfile": {
"id": "UUID_пользователя_без_дефисов",
"name": "Текущий_username_пользователя"
},
"user": { /* Только если передан параметр requestUser */
"id": "UUID_пользователя_без_дефисов",
"username": "Текущий_username_пользователя",
"properties": [
{
"name": "preferredLanguage",
"value": "ru"
}
]
}
}
```
### Проверка токена {#auth-validate}
Этот запрос позволяет проверить валиден ли указанный accessToken или нет. Этот запрос не обновляет токен и его время жизни, а только позволяет удостовериться, что он ещё действительный.
> **POST /auth/validate**
>
> **Параметры**:
> * **accessToken** (*string*) Токен доступа, полученный после авторизации
Успешным ответом будет являться пустое тело. При ошибке будет получен `400` или `401` статус. Пример ответа сервера при отправке истёкшего токена:
```json
{
"error": "ForbiddenOperationException",
"errorMessage": "Token expired."
}
```
### Инвалидация всех токенов пользователя {#auth-signout}
Этот запрос позволяет выполнить инвалидацию всех выданных пользователю токенов.
> **POST /auth/signout**
>
> **Параметры**:
> * **username** (*string*) Никнейм пользователя или его E-mail (более предпочтительно).
> * **password** (*string*) Пароль пользователя.
Успешным ответом будет являться пустое тело. Ориентируйтесь на поле `error` в теле ответа.
### Инвалидация токена {#auth-invalidate}
Запрос позволяет инвалидировать **accessToken**. В случае, если переданный токен не удастся найти в хранилище токенов, **ошибка не будет сгенерирована** и вы получите успешный ответ.
> **POST /auth/invalidate**
>
> **Параметры**:
> * **accessToken** (*string*) Уникальный ключ, полученный после авторизации.
> * **clientToken** (*string*) Уникальный идентификатор клиента, относительно которого получен accessToken.
Успешным ответом будет являться пустое тело. Ориентируйтесь на поле error в теле ответа.
## Авторизация на сервере {#server}
Эти запросы выполняются непосредственно клиентом и сервером при помощи внутреннего кода или библиотеки **authlib** (начиная с версии 1.7.2). Они актуальны только в том случае, если вы уже произвели авторизацию и запустили игру с валидным **accessToken**. Вам остаётся только заменить пути внутри игры/библиотеки на приведённые ниже пути.
Поскольку непосредственно изменить что-либо в работе **authlib** или игры вы не можете, здесь не приводятся передаваемые значения и ответы сервера. При необходимости вы сможете найти эту информацию самостоятельно в интернете.
### Через authlib {#authlib}
:::info
Эта часть документации описывает запросы, выполняемые через **authlib** в версии игры **1.7.2+**. Для более старых версий смотрите [раздел ниже](#legacy).
:::
Все запросы из этой категории выполняются на подуровень `/session`. Перед каждым из запросов указан тип отправляемого запроса.
> **POST /session/join**
>
> Запрос на этот URL производится клиентом в момент подключения к серверу с online-mode=true.
> **GET /session/hasJoined**
>
> Запрос на этот URL выполняет сервер с online-mode=true после того, как клиент, пытающийся к нему подключиться, успешно выполнит join запрос. Текстуры будут подписаны ключом Ely.by.
:::tip
Ключ для проверки подписи можно получить через [сервер системы скинов](./skins-system.md#signature-verification-key-request).
:::
:::danger
В редких случаях поле `signature` будет иметь значение `Cg==``. При таком значении поля подписи проводить её проверку **не нужно**, т.к. она всегда будет некорректной.
:::
### Для старых версий {#legacy}
:::info
Эта часть документации описывает запросы, выполняемые более старыми версиями Minecraft, в которых не применялась библиотека **Authlib**. Это все версии **ниже 1.7.2**.
:::
Все запросы из этой категории выполняются на подуровень `/session/legacy`. Перед каждым из запросов указан тип отправляемого запроса.
Принцип обработки этих запросов такой же, как и для **authlib**, отличие только во входных параметрах и возвращаемых значения.
> **GET /session/legacy/join**
>
> Запрос на этот URL производится клиентом в момент подключения к серверу с online-mode=true.
> **GET /session/legacy/hasJoined**
>
> Запрос на этот URL выполняет сервер с online-mode=true после того, как клиент, пытающийся к нему подключиться, успешно выполнит join запрос.
Важно не потерять GET параметр `?user=` в конце обоих запросов, чтобы получились следующие URL: `https://authserver.ely.by/session/legacy/hasJoined?user=`.
## Одиночная игра {#singleplayer}
По сути, одиночная игра - это локальный сервер, созданный для одного игрока. По крайней мере это так, начиная с **версии 1.6**, в которой и был представлен механизм локальных серверов.
Тем не менее, описанный ниже запрос актуален только для **Minecraft 1.7.6+**, когда для загрузки скинов стала использоваться Authlib.
> {#profile-request}**GET /session/profile/\{uuid\}**
>
> Запрос на этот URL выполняется клиентом в одиночной игре на локальном сервере (созданном посредством самой игры). В URL передаётся UUID пользователя, с которым был запущен клиент, а в ответ получается информация о текстурах игрока в таком же формате, как и при `hasJoined` запросе.
## Готовые библиотеки authlib {#premade-authlib}
:::tip
Ely.by поддерживает библиотеку authlib-injector. Это наиболее простой и универсальный способ установки системы авторизации в игру и игровые сервера. За подробностями обратитесь в [соответствующий раздел документации](./authlib-injector.md).
:::
Поскольку самостоятельная реализация связана с трудностями поиска исходников, подключения зависимостей и в конце-концов с процессом компиляции, на [странице загрузок нашей системы скинов](https://ely.by/load) вы можете загрузить уже готовые библиотеки со всеми необходимыми изменениями. Выберите в выпадающем списке необходимую версию и следуйте инструкции по установке, размещённой на той же странице ниже.
В более ранних версиях игры система скинов находилась внутри игрового клиента, так что библиотеки ниже обеспечивают лишь авторизацию:
* Minecraft 1.7.5 - [authlib 1.3.1](/authlib/authlib-1.3.1.jar)
* Minecraft 1.7.2 - [authlib 1.3](/authlib/authlib-1.3.jar)
Для установки вам необходимо заменить оригинальную библиотеку, располагающуюся по пути `<директория установки minecraft>/libraries/com/mojang/authlib/`. Убедитесь в том, что версии скачанного и заменяемого файлов совпадают.
:::warning
Многие лаунчеры и скрипты запуска серверов проверяют целостность файлов игры при запуске и могут не допускать подобную модификацию
:::
### Установка authlib на сервер {#authlib-server}
Сервер также использует **authlib** для выполнения авторизации игрока, поэтому соответствующие изменения должны быть также применены и к нему. Ниже приведены инструкции по установки **authlib** для различных реализаций сервера Minecraft.
#### Оригинальный сервер {#authlib-server-vanilla}
С помощью архиватора откройте файл сервера `minecraft_server.ВЕРСИЯ.jar`. Таким же образом откройте архив с authlib для соответствующей версии сервера. Перед вами будет два окна: одно с файлами сервера, другое с файлами authlib. Вам необходимо «перетащить» из архива с authlib все файлы и папки, **за исключением директории META-INF**, и подтвердить замену.
<figure>
![Перетягиваем содержимое authlib (кроме meta-inf) в содержимое сервера (в зону .class-файлов, не папок)](/img/authlib-install.png)
<figcaption>Обратите внимание: «перетягивать» содержимое нужно ниже папок сервера (в область файлов .class).</figcaption>
</figure>
После этих действий вы можете закрыть оба окна и в файле `server.properties` установить значение `online-mode=true`.
#### Bukkit/Spigot {#authlib-server-spigot}
Сперва выполните установку, как она описана для [оригинального сервера](#authlib-server-vanilla). Затем скачайте библиотеки [commons-io](https://repo1.maven.org/maven2/commons-io/commons-io/2.5/commons-io-2.5.jar) и [commons-lang3](https://repo1.maven.org/maven2/org/apache/commons/commons-lang3/3.5/commons-lang3-3.5.jar), после чего аналогичным с authlib образом последовательно переместите содержимое скачанных архивов в файлы сервера.
#### Forge/Sponge {#authlib-server-forge}
Прежде чем производить установку, необходимо определить, какой именно файл подлежит модификации:
* **>=1.16**: `libraries/net/minecraft/server/ВЕРСИЯ-ЦИФРЫ/server-ВЕРСИЯ-ЦИФРЫ-extra.jar`.
* **1.13-1.15**: `libraries/net/minecraft/server/ВЕРСИЯ/server-ВЕРСИЯ-extra.jar`.
* **<=1.12**: `minecraft_server.ВЕРСИЯ.jar`.
Когда необходимый файл найден, выполните для него установку authlib, аналогично [оригинальному серверу](#authlib-server-vanilla).
#### Paper (PaperSpigot и производные) {#authlib-server-paper}
Установка производится по аналогии с [Bukkit/Spigot](#authlib-server-spigot) в файл `cache/patched-ВЕРСИЯ.jar`. После внесения изменений, запускать сервер нужно через jar-файл из директории cache, поскольку в противном случае Paper восстановит исходное состояние файла:
```bash
# До
java -jar paper-ВЕРСИЯ-БИЛД.jar
# После
java -jar cache/patched-ВЕРСИЯ.jar
```
#### BungeeCord (и производные) {#authlib-server-bungeecord}
:::tip
Вы можете воспользоваться библиотекой [authlib-injector](./authlib-injector.md) для установки системы авторизации без модификации внутренностей сервера.
:::
Хотя BungeeCord и является проксирующим сервером, авторизацию игроков он выполняет самостоятельно. К сожалению, BungeeCord не опирается на использование Authlib, а реализует процесс авторизации самостоятельно, поэтому для установки системы авторизации Ely.by вам понадобится модифицировать скомпилированные `.class` файлы.
Для установки следуйте инструкции ниже:
1. Скачайте программу InClassTranslator (прямых ссылок не даём, но его легко найти).
2. С помощью архиватора откройте файл `BungeeCord.jar`.
3. Перейдите по пути `net/md_5/bungee/connection` и найдите там файл `InitialHandler.class` (без каких-либо символов `$`).
4. Распакуйте этот файл. В самом простом случае сделать это можно просто «вытянув» его из окна архиватора.
5. Откройте распакованный файл в программе **InClassTranslator** и замените в нём строку `https://sessionserver.mojang.com/session/minecraft/hasJoined?username=` на `https://authserver.ely.by/session/hasJoined?username=`, как показано на рисунке ниже:
![Замена строки через InClassTranslator](/img/bungeecord_inclasstranslator.png)
6. Сохраните изменения и перетащите измененный файл обратно в архив сервера. Подтвердите замену.
![Упаковка class-файла назад в jar](/img/bungeecord_move.png)
После выполнения этих действий вы можете указать в файле конфигурации BungeeCord (`config.yml`) значение `online_mode=true`.
:::info
Мы также рекомендуем выполнить установку Authlib на все сервера позади BungeeCord. Это может быть необходимо для плагинов, которые используют API Mojang. Инструкция по установке на конечные сервера [приведена выше](#authlib-server).
При этом все сервера должны иметь в своей конфигурации (`server.properties`) значение `online-mode=false`, поскольку пользователи уже авторизованы силами BungeeCord.
:::
## Установка на версии ниже 1.7.2 {#install-legacy}
Для более старых версий существует достаточно большое многообразие различных случаев, раскрыть которые в этой документации не представляется возможным. Вся установка заключается в замене определённых строк в определённых классах через **InClassTranslator**.
На форуме RuBukkit есть [отличный пост](http://www.rubukkit.org/threads/spisok-klassov-i-klientov-dlja-mcp.25108/#post-303710), в котором собрана вся нужна информация по именам классов на различных версиях Minecraft. Переписывать его сюда не имеет смысла, так что просто перейдите на его страницу и найдите нужную версию.
### Пример установки {#install-legacy-example}
Предположим, что вы хотите установить авторизацию на сервер версии **1.5.2**.
Сначала вы переходите по вышеприведённой ссылке, выбираете нужную версию (1.5.2) и видите список классов:
* `bdk.class` - путь до `joinserver`
* `jg.class` - путь до `checkserver`
Затем вы должны взять .jar файл клиента и открыть его любым архиватором. После чего вам необходимо найти файл **bdk.class**. Для этого удобно воспользоваться поиском.
После того, как вы нашли файл, его нужно извлечь из архива - просто перетащите его оттуда в удобную для вас дирикторию.
Дальше запустите **InClassTranslator** и в нём откройте этот класс. Слева будет список найденных в файле строк, которые вы можете изменить. Нужно заменить только строку, отвечающую за запрос на подключение к серверу:
![](/img/installing_by_inclasstranslator.png)
После этого вам нужно положить изменённый .class обратно в .jar файл игры.
Ту же самую операцию вам необходимо провести и с сервером, только заменить ссылку на `hasJoined`.
После этих действий вам нужно в настройках включить online-mode=true и сервер станет пускать на себя только тех игроков, которые будут авторизованы через Ely.by.

99
docs/oauth.md Normal file
View File

@@ -0,0 +1,99 @@
# Авторизация по протоколу 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 {#oauth-scopes}
| **Scope** | **Описание** |
|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **account_info** | Получение информации о пользователе. |
| **account_email** | В ответе на запрос информации о пользователе будет также присутствовать его email. |
| **offline_access** | Вместе с `access_token` вы также получите и `refresh_token`. Смотрите подробнее в [соответствующем разделе](#refresh-token-grant). |
| **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);
}
```
Пояснение к коду:
Сначала мы объявляем переменную `$oauthParams`, в которую заносим значения, полученные после регистрации приложения.
Затем проверяем, не возникла-ли ошибка. В этом случае сразу же прерываем выполнение.
Формируем POST запрос к форме обмена `code` на `access_token`, передавая необходимые поля.
Выполняем запрос, получаем ответ, переводим его из JSON в ассоциативный массив.