Поделиться через


Получение маркера доступа в веб-приложении Node.js

Область применения: Белый круг с серым символом X. клиенты рабочей силы внешниеЗеленый круг с символом белой галочки. клиенты (дополнительные сведения)

В этой статье вы обновите код, чтобы разрешить веб-приложению получать маркер доступа. Для упрощения добавления проверки подлинности и авторизации в веб-приложение узла используется библиотека проверки подлинности Майкрософт (MSAL). Эта статья является третьей частью серии руководств с четырьмя частью.

Необходимые компоненты

Обновление объекта конфигурации MSAL

В редакторе кода откройте файл authConfig.js , а затем обновите код, добавив protectedResources объект:

    //..   
    const toDoListReadScope = process.env.TODOLIST_READ || 'api://Enter_the_Web_Api_Application_Id_Here/ToDoList.Read';
    const toDoListReadWriteScope = process.env.TODOLIST_READWRITE || 'api://Enter_the_Web_Api_Application_Id_Here/ToDoList.ReadWrite';
    
    const protectedResources = {
        toDoListAPI: {
            endpoint: 'https://localhost:44351/api/todolist',
            scopes: {
                read: [toDoListReadScope],
                write: [toDoListReadWriteScope],
            },
        },
    };    
    module.exports = {
        //..
        protectedResources,
        //..
    };

В файле authConfig.js замените Enter_the_Web_Api_Application_Id_Here идентификатор приложения (клиента) веб-API, зарегистрированного в клиенте клиента.

todolistReadWriteScope Переменные todolistReadScope содержат URL-адреса полной области веб-API, заданные во внешнем клиенте. Убедитесь, что вы экспортируете protectedResources объект.

Получение маркера доступа

В редакторе кода откройте файл проверки подлинности/AuthProvider.js , а затем обновите getToken метод в AuthProvider классе:

    const axios = require('axios');
    class AuthProvider {
    //...
        getToken(scopes) {
            return  async function (req, res, next) {
                const msalInstance = authProvider.getMsalInstance(authProvider.config.msalConfig);
                try {
                    msalInstance.getTokenCache().deserialize(req.session.tokenCache);
    
                    const silentRequest = {
                        account: req.session.account,
                        scopes: scopes,
                    };
    
                    const tokenResponse = await msalInstance.acquireTokenSilent(silentRequest);
    
                    req.session.tokenCache = msalInstance.getTokenCache().serialize();
                    req.session.accessToken = tokenResponse.accessToken;
                    next();
                } catch (error) {
                    if (error instanceof msal.InteractionRequiredAuthError) {
                        req.session.csrfToken = authProvider.cryptoProvider.createNewGuid();
    
                        const state = authProvider.cryptoProvider.base64Encode(
                            JSON.stringify({
                                redirectTo: 'http://localhost:3000/todos',
                                csrfToken: req.session.csrfToken,
                            })
                        );
                        
                        const authCodeUrlRequestParams = {
                            state: state,
                            scopes: scopes,
                        };
    
                        const authCodeRequestParams = {
                            state: state,
                            scopes: scopes,
                        };
    
                        authProvider.redirectToAuthCodeUrl(
                            req,
                            res,
                            next,
                            authCodeUrlRequestParams,
                            authCodeRequestParams,
                            msalInstance
                        );
                    }
    
                    next(error);
                }
            };
        }
    //...
    }
  • Во-первых, функция пытается автоматически получить маркер доступа (не запрашивая у пользователя учетные данные):

    const silentRequest = {
        account: req.session.account,
        scopes: scopes,
    };
    
    const tokenResponse = await msalInstance.acquireTokenSilent(silentRequest);
    
  • Если маркер успешно получен автоматически, сохраните его в сеансе. Маркер извлекается из сеанса при вызове API.

    req.session.accessToken = tokenResponse.accessToken;
    
  • Если не удается получить маркер автоматически (например, с InteractionRequiredAuthError исключением), запросите маркер доступа.

Примечание.

После получения маркера доступа клиентское приложение должно рассматриваться как непрозрачная строка. Маркер доступа предназначен для API, а не для клиентского приложения. Поэтому клиентское приложение не должно пытаться считывать или обрабатывать маркер доступа. Вместо этого он должен включать маркер доступа как находится в заголовке авторизации своих запросов к API. API отвечает за интерпретацию маркера доступа и его использование для проверки подлинности и авторизации запросов клиентского приложения.

Следующий шаг