...

Пользовательский модуль OAuth2 для авторизации через Яндекс ID

Тема в разделе "Примеры решений и дополнительных модулей", создана пользователем vyimova, 19 апр 2023.

  1. vyimova

    vyimova Участник

    OAuth 2.0 – это протокол авторизации. Он описывает, как должно реализовываться взаимодействие между сервисами/приложениями для обеспечения безопасной авторизации. Протокол позволяет выдать одному сервису ограниченный доступ к пользовательским аккаунтам на другом сервисе и таким образом делегировать аутентификацию пользователя сервису, на котором находится существующий аккаунт пользователя. При этом пользователь не передает свои логин и пароль напрямую в приложение, которое использует ресурсы другого сервиса.

    На основе этого протокола ELMA365 позволяет реализовать регистрацию и авторизацию пользователей через сторонние сервисы. Для этого необходимо создать и настроить пользовательский модуль OAuth2. После включения модуля новый способ авторизации станет доступен на стенде ELMA365.

    Разберем пример модуля для авторизации через Яндекс ID.

    Алгоритм взаимодействия:

    [​IMG]
    (Иллюстрация на основе статьи «OAuth 2.0 простым и понятным языком»).

    Создание модуля и внешнего приложения
    Создаем пользовательский модуль на стенде. Рекомендуется добавить к модулю иконку сервиса, т.к. в дальнейшем если на стенде есть несколько сервисов, которые используют протокол OAuth2, то в них пользователю проще ориентироваться в настройках по иконкам.

    [​IMG]

    В данном случае наш сервис – Яндекс ID. У него есть отличная справка по API Яндекс ID и использованию OAuth2, советуем ознакомиться: https://yandex.ru/dev/id/doc/ru/. Значения url и наименований полей из ответа на запрос получения информации о пользователе – взяты из данной справки. При реализации пользовательского модуля для взаимодействия с каким-либо другим сервисом (не Яндекс ID), нужно будет использовать документацию именно по сервису, с которым будет взаимодействие, и искать в ней необходимые значения.

    Создаем Внешнее приложение на стороне сервиса, через который будем авторизовываться на стенде ELMA365. Ссылка, по которой для Яндекса можно создать Внешнее приложение: https://oauth.yandex.ru/.

    Нажимаем кнопку «Создать приложение».

    [​IMG]

    Название задаем любое, понятное для самих себя. Среди списка платформ приложения выбираем «Веб-сервисы».

    [​IMG]

    Среди доступа к данным выбираем пункт «Доступ к адресу электронной почты».

    [​IMG]

    Электронная почта нам нужна для возможности создания нового пользователя. Также в Яндексе автоматически выдается доступ на идентификатор (id) пользователя, необходимый для успешной авторизации, так как для авторизации через OAuth2 должно быть соответствия логина пользователя ELMA365 и логина пользователя стороннего сервиса.

    Далее вводим Redirect URI. Для ELMA365 он составляется по следующей маске:
    https://стенд/_oauth2/post-message?provider=id_модуля,
    где:
    «стенд» – url вашего стенда,
    «id_модуля» – id модуля, который вы создали ранее и где предполагается настройка OAuth2. Префикс «ext_» в ссылке писать не нужно.

    Приложение создано. На странице этого приложения видим поля ClientID и Client secret. Они пригодятся нам далее.

    [​IMG]


    Настройка контекста модуля

    Возвращаемся в настройки нашего модуля. Создаем на вкладке «Настройки» поля client_id, client_secret, auth_url, token_url, scopes, auto_signup.

    Разберем что означает каждое поле и где взять значение.

    Поля типа «Строка»:

    • client_id – идентификатор приложения. Значение есть на странице приложения;
    • client_secret – секретный ключ приложения. Значение есть на странице приложения;
    • auth_url – адрес аутентификации, url для выполнения запроса Получения кода подтверждения. Для Яндекса url будет - https://oauth.yandex.ru/authorize, параметры не вводим;
    • token_url – адрес токена доступа, url для выполнения запроса Обмена кода подтверждения на OAuth-токен. Для Яндекса url будет - https://oauth.yandex.ru/token, параметры не вводим;
    • scopes – права доступа. Для Яндекса вводим: login:email. Узнать допустимые права можно по ссылке https://oauth.yandex.ru/client/<client_id>/info, указав вместо <client_id> идентификатор своего Внешнего приложения.
    Поле типа «Выбор да/нет»:
    • auto_signup – необходим для обозначения, нужно ли создавать пользователя ELMA365, если не нашлось соответствия с существующим пользователем.
    Все вышеперечисленные поля выносим на форму модуля и делаем их обязательными. Заполняем.

    [​IMG]

    Настройка сценария Метода API
    Переходим на вкладку «Методы API». Нажимаем кнопку «Редактировать». Заходим на вкладку «Сценарии».

    Вводим следующий код:
    Код:
    
    interface AccessTokenData {
        
    access_tokenstring;
        
    refresh_tokenstring;
        
    token_typestring;
        
    expires_innumber;
    }

    interface 
    OAuth2Profile {
        
    // идентификатор пользователя (id/sub)
        
    user_idstring;
        
    // email пользователя
        
    emailstring;
    }

    interface 
    OAuth2ResponseFail {
        
    errorstring;
        
    error_descriptionstring;
    }

    async function oauth2_profile (tokenDataAccessTokenData): Promise<OAuth2Profile OAuth2ResponseFail> {
        
    // данный url - только для Яндекса
        // для другого сервиса будет свой url для получения данных пользователя
        
    const user_info await fetch(`https://login.yandex.ru/info?format=json`,{
            
    method'GET',
            
    headers: {
                
    Authorization'OAuth ' tokenData.access_token.toString()
            }
        });
        if (
    user_info.ok) {
            const 
    body await user_info.json();

            if (
    body.error) {
                return <
    OAuth2ResponseFail> {
                    
    errorbody.error.error_code.toString(),
                    
    error_descriptionbody.error.error_msg,
                }
            }

            if (
    body.length == 0) {
                return <
    OAuth2ResponseFail> {
                    
    error"user_not_found",
                    
    error_description"User not found!"
                
    };
            }

            return <
    OAuth2Profile> {
                
    // наименования полей "id" и "default_email" - только для Яндекса
                // для других сервисов наименования могут быть другими, они зависят от со-держимого ответа сервиса, нужно смотреть документацию
                
    user_idbody.id.toString(),
                
    emailbody.default_email.toString()
            };
        }

        return <
    OAuth2ResponseFail> {
            
    erroruser_info.statusText,
            
    error_descriptionawait user_info.text()
        };
    }
    Данный код типовой для всех сервисов. Меняться могут:

    • url в запросе, в данном примере использован url Яндекса для получения данных о пользователе;
    • список полей интерфейса OAuth2Profile. Может, например, добавиться поле для ФИО. Соответственно, в return также добавится новое поле;
    • важно! наименования полей из body. Для Яндекса поля идентификатора и почты соответственно равны id и default_email. Но в других сервисах наименования будут другими, нужно смотреть структуру ответа каждого конкретного сервиса.
    Модуль настроен и готов к тестированию.

    Тестирование

    Самый быстрый способ тестирования – зайти под текущим пользователем в настройки пользователя на вкладку «Аутентификация». На вкладке будет заголовок «Привязать аккаунт OAuth2 провайдера» и список приложений, у которых настроен OAuth2, в том числе наше приложение с кнопкой «Привязать».

    [​IMG]

    Нажимаем на кнопку «Привязать». В появившемся новом окне вводим креды от учетной записи стороннего сервиса, под которой хотим зайти и которую хотим связать с нашим пользователем ELMA. Если в браузере уже сохранена авторизация в стороннем сервисе, ввод кред может не понадобиться.

    При успешной привязке учетной записи, кнопка «Привязать» сменится на кнопку «Удалить». Теперь можно тестировать вход на стенд под данной учетной записью через сторонний сервис.

    Выходим из учетной записи. Для чистоты эксперимента можно зайти в режим «Инкогнито» браузера. У нас открывается страница авторизации:

    [​IMG]

    Нажимаем кнопку «Войти другим способом».

    В появившейся форме выбираем наш модуль. В данном случае он называется «Аутентификация Яндекс».

    [​IMG]

    В появившемся окне вводим логин и пароль от учетной записи сервиса. В случае успешной настройки модуля и корректных введенных значений у нас произошла авторизация на стенд в нашу учетную запись, которую мы связали чуть ранее с учетной записью стороннего сервиса.

    В случае, если у нас в параметрах модуля «auto_signup» находится в значении «Да», то также можно создать нового пользователя. В случае, если у учетной записи стороннего сервиса нет привязки ни с одним пользователем ELMA, т.е. ни под одним пользователем не было осуществлено привязки в настройках, которая была описана выше, то будет создан новый пользователь с email, который будет взят из стороннего сервиса для данной учетной записи.

    Во вложениях приведен пример готового пользовательского модуля «Аутентификация Яндекс».

    Вложения:

    Последнее редактирование: 19 апр 2023