Udostępnij za pośrednictwem


Samouczek: Wywoływanie sieciowego API z aplikacji demona Node.js

Ten samouczek jest ostatnią częścią serii, która pokazuje, jak przygotować aplikację kliencką demona Node.js przy użyciu open authorization (OAuth) 2.0 client credentials grant flow, a następnie skonfigurować go w celu uzyskania tokenu dostępu do wywoływania internetowego interfejsu API. W części 1 tej seriizarejestrowano internetowy interfejs API i aplikację działającą w tle w centrum administracyjnym Microsoft Entra oraz udzielono uprawnień. W tym ostatnim kroku pokazano, jak utworzyć aplikację Node.js przy użyciu biblioteki Microsoft Authentication Library (MSAL) dla środowiska Node w celu uproszczenia dodawania autoryzacji do aplikacji.

W tym samouczku;

  • Utwórz aplikację Node.js w programie Visual Studio Code, a następnie zainstaluj zależności.
  • Włącz aplikację Node.js, aby uzyskać token dostępu do wywoływania internetowego interfejsu API.

Warunki wstępne

  • Poradnik: Przygotuj swoją zewnętrzną dzierżawę do autoryzacji aplikacji demona Node.js.
  • Chroniony internetowy interfejs API, który jest uruchomiony i gotowy do akceptowania żądań. Jeśli jeszcze tego nie zrobiłeś, zobacz samouczek o tworzeniu chronionego API internetowego . Upewnij się, że ten internetowy API używa szczegółów rejestracji aplikacji, które utworzyłeś w samouczku przygotowywania dzierżawy . Upewnij się, że internetowy interfejs API uwidacznia następujące punkty końcowe za pośrednictwem protokołu HTTPS:
    • GET /api/todolist, aby uzyskać wszystkie zadania.
    • POST /api/todolist aby dodać TODO.
  • Node.js.
  • Mimo że można używać dowolnego zintegrowanego środowiska projektowego (IDE), które obsługuje aplikacje React, w tym samouczku jest używana programu Visual Studio Code.
  • Szczegóły rejestracji aplikacji demona Node.js i internetowego interfejsu API utworzonego w samouczku przygotowywania dzierżawy .

Tworzenie projektu demona Node.js

Utwórz folder do hostowania aplikacji demona Node.js, na przykład ciam-call-api-node-daemon:

  1. W terminalu przejdź do katalogu swojej aplikacji demon Node.js, na przykład cd ciam-call-api-node-daemon, a następnie uruchom polecenie npm init -y. To polecenie tworzy domyślny plik package.json dla projektu Node.js. To polecenie tworzy domyślny plik package.json dla projektu Node.js.

  2. Utwórz dodatkowe foldery i pliki, aby uzyskać następującą strukturę projektu:

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

Instalowanie zależności aplikacji

W terminalu zainstaluj pakiety axios, yargs i @azure/msal-node, uruchamiając następujące polecenie:

npm install axios yargs @azure/msal-node   

Tworzenie obiektu konfiguracji biblioteki MSAL

W edytorze kodu otwórz plik authConfig.js, a następnie dodaj następujący kod:

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,
};

Obiekt msalConfig zawiera zestaw opcji konfiguracji używanych do dostosowywania zachowania przepływu autoryzacji.

W pliku authConfig.js zastąp:

  • Enter_the_Application_Id_Here z użyciem identyfikatora aplikacji (klienta) dla klienta demona, którą zarejestrowałeś wcześniej.

  • Enter_the_Tenant_Subdomain_Here i zastąp ją poddomeną Katalog (dzierżawa). Jeśli na przykład domena podstawowa dzierżawy jest contoso.onmicrosoft.com, użyj contoso. Jeśli nie masz nazwy dzierżawcy, dowiedz się, jak sprawdzać szczegóły dzierżawy.

  • Enter_the_Client_Secret_Here ze skopiowaną wcześniej tajną wartością aplikacji klienta-demona.

  • Enter_the_Web_Api_Application_Id_Here za pomocą identyfikatora aplikacji (klienta) skopiowanej wcześniej aplikacji internetowego interfejsu API.

Zwróć uwagę, że właściwość scopes w zmiennej protectedResources to identyfikator zasobu (identyfikator URI identyfikatora aplikacji) internetowego interfejsu API, który został wcześniej zarejestrowany. Pełny URI zakresu wygląda podobnie do api://Enter_the_Web_Api_Application_Id_Here/.default.

Uzyskiwanie tokenu dostępu

W edytorze kodu otwórz plik auth.js, a następnie dodaj następujący kod:

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,
};

W kodzie:

  • Przygotuj obiekt tokenRequest i apiConfig. tokenRequest zawiera zakres żądania tokenu dostępu. Zakres wygląda podobnie do api://Enter_the_Web_Api_Application_Id_Here/.default. Obiekt apiConfig zawiera punkt końcowy interfejsu API sieci webowej. Dowiedz się więcej o przepływie poświadczeń klienta OAuth 2.0 .

  • Instancję klienta poufnego tworzysz poprzez przekazanie obiektu msalConfig do konstruktora klasy ConfidentialClientApplication.

    const cca = new msal.ConfidentialClientApplication(msalConfig);
    
  • Następnie użyjesz funkcji acquireTokenByClientCredential, aby uzyskać token dostępu. Tę logikę należy zaimplementować w funkcji getToken:

    cca.acquireTokenByClientCredential(tokenRequest);
    

Po uzyskaniu tokenu dostępu możesz przejść do wywołania interfejsu API.

Wywoływanie interfejsu API

W edytorze kodu otwórz plik fetch.js, a następnie dodaj następujący kod:

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
};

W tym kodzie wykonujesz wywołanie webowego API, przekazując token dostępu jako token typu bearer w nagłówku żądania Authorization.

 Authorization: `Bearer ${accessToken}`

Używasz tokenu dostępu uzyskanego wcześniej w Uzyskiwanie tokenu dostępu.

Po odebraniu żądania przez internetowy interfejs API ocenia go, a następnie określa, że jest to żądanie aplikacji. Jeśli token dostępu jest prawidłowy, internetowy interfejs API zwraca żądane dane. W przeciwnym razie interfejs API zwraca błąd HTTP 401 Unauthorized.

Finalizowanie aplikacji demona

W edytorze kodu otwórz plik index.js, a następnie dodaj następujący kod:

#!/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();

Ten kod jest punktem wejścia do aplikacji. Używasz biblioteki analizy argumentów wiersza polecenia yargs JavaScript dla aplikacji Node.js, aby interaktywnie pobrać token dostępu, a następnie wywołać interfejs API. Używasz zdefiniowanych wcześniej funkcji getToken i callApi:

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

Uruchamianie i testowanie aplikacji demona i interfejsu API

Na tym etapie możesz przetestować aplikację demona klienta i internetowy interfejs API:

  1. Wykonaj kroki poznane w samouczku Secure an ASP.NET web API, aby uruchomić internetowy interfejs API. Internetowy interfejs API jest teraz gotowy do obsługi żądań klientów. Jeśli nie uruchamiasz internetowego interfejsu API na porcie 44351 zgodnie z opisem w pliku authConfig.js, upewnij się, że zaktualizowano plik authConfig.js, aby używał poprawnego numeru portu internetowego interfejsu API.

  2. W terminalu upewnij się, że znajdujesz się w folderze projektu zawierającym aplikację demon Node.js, taką jak ciam-call-api-node-daemon, a następnie uruchom następujące polecenie:

    node . --op getToDos
    

Jeśli aplikacja demona i internetowy interfejs API zostały pomyślnie uruchomione, należy znaleźć dane zwrócone przez zmienną internetowego punktu końcowego interfejsu API todos podobną do następującej tablicy JSON w oknie konsoli:

{
    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'
}

Następny krok