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


Руководство. Вызов веб-API из приложения управляющей программы Node.js

В этом руководстве представлена последняя часть серии, демонстрирующая подготовку клиентского приложения Node.js управляющей программы с помощью потока предоставления учетных данных клиента Open Authorization (OAuth) 2.0, а затем настроить его для получения маркера доступа для вызова веб-API. В части 1 этой серии вы зарегистрировали веб-API и приложение управляющей программы в Центре администрирования Microsoft Entra и предоставили разрешения. На последнем шаге показано, как создать приложение Node.js с помощью библиотеки проверки подлинности Майкрософт (MSAL) для узла , чтобы упростить добавление авторизации в приложение.

В этом руководстве;

  • Создайте приложение Node.js в Visual Studio Code, а затем установите зависимости.
  • Включите приложение Node.js получить маркер доступа для вызова веб-API.

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

  • Руководство. Подготовка внешнего клиента для авторизации приложения управляющей программы Node.js.
  • Защищенный веб-API, который выполняется и готов принимать запросы. Если вы еще не создали его, ознакомьтесь с руководством по созданию защищенного веб-API. Убедитесь, что этот веб-API использует сведения о регистрации приложения, созданные в руководстве по подготовке клиента. Убедитесь, что веб-API предоставляет следующие конечные точки через HTTPS:
    • GET /api/todolist Чтобы получить все додосы.
    • POST /api/todolist , чтобы добавить TODO.
  • Node.js.
  • Хотя можно использовать любую интегрированную среду разработки (IDE), поддерживающую приложения React, в этом руководстве используется Visual Studio Code.
  • Сведения о регистрации для приложения Node.js управляющей программы и веб-API, созданного в руководстве по подготовке клиента.

Создание проекта управляющей программы Node.js

Создайте папку для размещения приложения управляющей программы Node.js, например ciam-call-api-node-daemon:

  1. В терминале измените каталог в папку приложения управляющей программы узла, например cd ciam-call-api-node-daemon, а затем запустите npm init -y. Эта команда создает файл по умолчанию package.json для вашего проекта Node.js. Эта команда создает файл по умолчанию package.json для проекта Node.js.

  2. Создайте дополнительные папки и файлы для достижения следующей структуры проекта:

        ciam-call-api-node-daemon/
        ├── auth.js
        └── authConfig.js
        └── fetch.js
        └── index.js 
        └── package.json
    

Установка зависимостей приложения

В терминале установите axiosyargs и @azure/msal-node пакеты, выполнив следующую команду:

npm install axios yargs @azure/msal-node   

Создание объекта конфигурации MSAL

В редакторе кода откройте файл authConfig.js , а затем добавьте следующий код:

require('dotenv').config();

/**
 * Configuration object to be passed to MSAL instance on creation.
 * For a full list of MSAL Node configuration parameters, visit:
 * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/configuration.md
 */    
const msalConfig = {
    auth: {
        clientId: process.env.CLIENT_ID || 'Enter_the_Application_Id_Here', // 'Application (client) ID' of app registration in Azure portal - this value is a GUID
        authority: process.env.AUTHORITY || 'https://Enter_the_Tenant_Subdomain_Here.ciamlogin.com/', // Replace "Enter_the_Tenant_Subdomain_Here" with your tenant subdomain
        clientSecret: process.env.CLIENT_SECRET || 'Enter_the_Client_Secret_Here', // Client secret generated from the app 
    },
    system: {
        loggerOptions: {
            loggerCallback(loglevel, message, containsPii) {
                console.log(message);
            },
            piiLoggingEnabled: false,
            logLevel: 'Info',
        },
    },
};    
const protectedResources = {
    apiToDoList: {
        endpoint: process.env.API_ENDPOINT || 'https://localhost:44351/api/todolist',
        scopes: [process.env.SCOPES || 'api://Enter_the_Web_Api_Application_Id_Here'],
    },
};

module.exports = {
    msalConfig,
    protectedResources,
};

Объект msalConfig содержит набор параметров конфигурации, используемых для настройки поведения потока авторизации.

В файле authConfig.js замените:

  • Enter_the_Application_Id_Here с идентификатором приложения (клиента) клиентского управляющей программы, зарегистрированного ранее.

  • Enter_the_Tenant_Subdomain_Here и замените его поддоменом каталога (клиента). Например, если основной домен клиента — это contoso.onmicrosoft.com, используйте contoso. Если у вас нет имени клиента, узнайте, как прочитать сведения о клиенте.

  • Enter_the_Client_Secret_Here значение секрета приложения управляющей программы клиента, скопированное ранее.

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

Обратите внимание, что scopes свойство в protectedResources переменной — это идентификатор ресурса (URI идентификатора приложения) веб-API , зарегистрированного ранее. Полный URI область выглядит примерно такapi://Enter_the_Web_Api_Application_Id_Here/.default.

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

В редакторе кода откройте файл auth.js , а затем добавьте следующий код:

const msal = require('@azure/msal-node');
const { msalConfig, protectedResources } = require('./authConfig');
/**
 * With client credentials flows permissions need to be granted in the portal by a tenant administrator.
 * The scope is always in the format '<resource-appId-uri>/.default'. For more, visit:
 * https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow
 */
const tokenRequest = {
    scopes: [`${protectedResources.apiToDoList.scopes}/.default`],
};

const apiConfig = {
    uri: protectedResources.apiToDoList.endpoint,
};

/**
 * Initialize a confidential client application. For more info, visit:
 * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/initialize-confidential-client-application.md
 */
const cca = new msal.ConfidentialClientApplication(msalConfig);
/**
 * Acquires token with client credentials.
 * @param {object} tokenRequest
 */
async function getToken(tokenRequest) {
    return await cca.acquireTokenByClientCredential(tokenRequest);
}

module.exports = {
    apiConfig: apiConfig,
    tokenRequest: tokenRequest,
    getToken: getToken,
};

В коде:

  • tokenRequest Подготовка и apiConfig объект. Содержит tokenRequest область, для которых запрашивается маркер доступа. Область выглядит примерно такapi://Enter_the_Web_Api_Application_Id_Here/.default. Объект apiConfig содержит конечную точку веб-API. Дополнительные сведения о потоке учетных данных клиента OAuth 2.0.

  • Вы создаете конфиденциальный экземпляр клиента, передав msalConfig объект конструктору класса ConfidentialClientApplication .

    const cca = new msal.ConfidentialClientApplication(msalConfig);
    
  • Затем вы используете функцию acquireTokenByClientCredential для получения маркера доступа. Эта логика реализуется getToken в функции:

    cca.acquireTokenByClientCredential(tokenRequest);
    

После получения маркера доступа можно перейти к вызову API.

Вызов API

В редакторе кода откройте файл fetch.js , а затем добавьте следующий код:

const axios = require('axios');

/**
 * Calls the endpoint with authorization bearer token.
 * @param {string} endpoint
 * @param {string} accessToken 
 */
async function callApi(endpoint, accessToken) {

    const options = {
        headers: {
            Authorization: `Bearer ${accessToken}`
        }
    };

    console.log('request made to web API at: ' + new Date().toString());

    try {
        const response = await axios.get(endpoint, options);
        return response.data;
    } catch (error) {
        console.log(error)
        return error;
    }
};

module.exports = {
    callApi: callApi
};

В этом коде выполняется вызов к веб-API, передав маркер доступа в качестве маркера носителя в заголовке запроса Authorization :

 Authorization: `Bearer ${accessToken}`

Вы используете маркер доступа, полученный ранее в разделе "Получение маркера доступа".

После получения запроса веб-API он оценивает его, а затем определяет, что это запрос приложения. Если маркер доступа действителен, веб-API возвращает запрошенные данные. В противном случае API возвращает ошибку 401 Unauthorized HTTP.

Завершение приложения управляющей программы

В редакторе кода откройте файл index.js , а затем добавьте следующий код:

#!/usr/bin/env node

// read in env settings

require('dotenv').config();

const yargs = require('yargs');
const fetch = require('./fetch');
const auth = require('./auth');

const options = yargs
    .usage('Usage: --op <operation_name>')
    .option('op', { alias: 'operation', describe: 'operation name', type: 'string', demandOption: true })
    .argv;

async function main() {
    console.log(`You have selected: ${options.op}`);

    switch (yargs.argv['op']) {
        case 'getToDos':
            try {
                const authResponse = await auth.getToken(auth.tokenRequest);
                const todos = await fetch.callApi(auth.apiConfig.uri, authResponse.accessToken);                
            } catch (error) {
                console.log(error);
            }

            break;
        default:
            console.log('Select an operation first');
            break;
    }
};

main();

Этот код является точкой входа в приложение. Вы используете библиотеку синтаксического анализа аргумента JavaScript yargs для Node.js приложений для интерактивного получения маркера доступа, а затем вызова API. Вы используете getToken определенные ранее функции и callApi функции:

const authResponse = await auth.getToken(auth.tokenRequest);
const todos = await fetch.callApi(auth.apiConfig.uri, authResponse.accessToken);                

Запуск и тестирование приложения управляющей программы и API

На этом этапе вы готовы протестировать клиентское приложение управляющей программы и веб-API:

  1. Выполните действия, описанные в руководстве по безопасному ASP.NET веб-API, чтобы запустить веб-API . Веб-API теперь готов обслуживать клиентские запросы. Если веб-API не запускается через порт44351, как указано в файле authConfig.js, убедитесь, что вы обновите файл authConfig.js, чтобы использовать правильный номер порта веб-API.

  2. В терминале убедитесь, что вы находитесь в папке проекта, содержащей управляющую программу Node.js приложение, например ciam-call-api-node-daemon, а затем выполните следующую команду:

    node . --op getToDos
    

Если управляющая программа и веб-API выполняются успешно, в окне консоли должны находиться данные, возвращаемые переменной конечной точки todos веб-API, аналогично следующему массиву JSON:

{
    id: 1,
    owner: '3e8....-db63-43a2-a767-5d7db...',
    description: 'Pick up grocery'
},
{
    id: 2,
    owner: 'c3cc....-c4ec-4531-a197-cb919ed.....',
    description: 'Finish invoice report'
},
{
    id: 3,
    owner: 'a35e....-3b8a-4632-8c4f-ffb840d.....',
    description: 'Water plants'
}

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