Авторизация по протоколу OAuth2 ------------------------------- На этой странице вы найдёте информацию о реализации авторизации по протоколу OAuth2 на вашем проекте через сервис Аккаунты Ely.by. Реализация этого протокола позволяет вашим пользователям производить авторизацию с использованием своего аккаунта Ely.by. Регистрация приложения ====================== Для начала вам необходимо `создать новое приложение `_. Выберите тип приложения **Веб‑сайт**. В качестве *адреса переадресации* можно указать только домен, но для повышения безопасности лучше использовать полный путь переадресации. Примеры допустимых адресов: * ``http://site.com`` * ``http://site.com/oauth/ely`` * ``http://site.com/oauth.php?provider=ely`` После успешного добавления приложения вы попадёте на страницу со списком всех ваших приложений. Кликнув по названию приложения вы увидите его идентификатор ``clientId`` и секрет ``clientSecret``. Они буду использоваться на следующих шагах. Инициализация авторизации ========================= Для инициализации процесса авторизации вам необходимо перенаправить пользователя по следующему URL: .. code-block:: text https://account.ely.by/oauth2/v1?client_id=&redirect_uri=&response_type=code&scope= .. list-table:: Допустимые параметры запроса :widths: 1 1 98 :header-rows: 1 * - Параметр - Пример значения - Описание * - *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 пользователя вы автоматически выберете аккаунт за него. Это полезно в случае повторного входа, когда токен истёк. .. _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 Войти через Ely.by По нажатию на ссылку, пользователь попадёт на нашу страницу авторизации, откуда после он будет перенаправлен обратно по адресу, указанному в параметре ``redirect_uri``. Обратная переадресация выполняется в виде ``?code=<код авторизации>&state=`` для успешной авторизации и ``&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 '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 `_, но со следующими параметрами: .. list-table:: :widths: 1 99 :header-rows: 0 * - ``client_id`` - ClientID, полученный при регистрации приложения. * - ``client_secret`` - ClientSecret, полученный при регистрации приложения. * - ``scope`` - Те же scope, что были запрошены и при получении начального токена доступа. Попытка запросить большее количество прав приведёт к ошибке. * - ``refresh_token`` - Непосредственно токен, полученный вместе с начальным токеном доступа. **Пример реализации обновления токена доступа на PHP:** .. code-block:: php '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**: - [Официальная] https://github.com/elyby/league-oauth2-provider * **Ruby**: - [Официальная] https://github.com/elyby/omniauth-ely Возможные ошибки ================ Ниже приведены стандартные ошибки, которые вы можете получить в случае неправильной передачи данных на сервер авторизации. Если вы столкнулись с ошибкой, не описанной в этой документации, пожалуйста, сообщите о ней через `форму обратной связи `_. .. _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 или запрошено больше, чем было у изначального токена.