Udostępnij za pośrednictwem


Samouczek: wywoływanie internetowego interfejsu 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 przepływu udzielania poświadczeń klienta open authorization (OAuth) 2.0, a następnie skonfigurować go do uzyskania tokenu dostępu do wywoływania internetowego interfejsu API. w części 1 tej serii zarejestrowano internetowy interfejs API i aplikację demona w centrum administracyjnym firmy Microsoft Entra i udzielono uprawnień. W tym ostatnim kroku pokazano, jak utworzyć aplikację Node.js przy użyciu biblioteki Microsoft Authentication Library (MSAL) dla środowiska Node , aby uprościć dodawanie 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.

Wymagania wstępne

  • Samouczek: przygotowanie dzierżawy zewnętrznej do autoryzowania aplikacji demona Node.js.
  • Chroniony internetowy interfejs API, który jest uruchomiony i gotowy do akceptowania żądań. Jeśli go nie utworzono, zapoznaj się z samouczkiem dotyczącym tworzenia chronionego internetowego interfejsu API. Upewnij się, że ten internetowy interfejs API używa szczegółów rejestracji aplikacji utworzonych 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 todos.
    • 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żywany program 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 zmień katalog na folder aplikacji demona node, taki jak cd ciam-call-api-node-daemon, a następnie uruchom polecenie npm init -y. To polecenie tworzy domyślny plik package.json dla projektu platformy Node.js. To polecenie tworzy plik domyślny 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 axiosyargs 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 za pomocą identyfikatora aplikacji (klienta) zarejestrowanej wcześniej aplikacji demona klienta.

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

  • Enter_the_Client_Secret_Here z skopiowaną wcześniej wartością wpisu tajnego aplikacji demona klienta.

  • Enter_the_Web_Api_Application_Id_Here z identyfikatorem aplikacji (klienta) skopiowanej wcześniej aplikacji internetowego interfejsu API.

Zwróć uwagę, że scopes właściwość w zmiennej protectedResources to identyfikator zasobu (identyfikator URI identyfikatora aplikacji) zarejestrowanego wcześniej internetowego interfejsu API . Pełny identyfikator 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:

  • tokenRequest Przygotuj obiekt i apiConfig . Zawiera tokenRequest zakres, dla którego żądasz tokenu dostępu. Zakres wygląda mniej więcej tak: api://Enter_the_Web_Api_Application_Id_Here/.default. Obiekt apiConfig zawiera punkt końcowy interfejsu API sieci Web. Dowiedz się więcej o przepływie poświadczeń klienta OAuth 2.0.

  • Wystąpienie klienta poufnego jest tworzone przez przekazanie msalConfig obiektu do konstruktora klasy ConfidentialClientApplication .

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

    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 wykonasz wywołanie internetowego interfejsu API, przekazując token dostępu jako token elementu nośnego w nagłówku żądania Authorization :

 Authorization: `Bearer ${accessToken}`

Użyj tokenu dostępu uzyskanego wcześniej w sekcji 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 401 Unauthorized błąd HTTP.

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. Biblioteka analizowania argumentów wiersza polecenia yargs w języku JavaScript służy do interaktywnego pobierania tokenu dostępu w aplikacjach Node.js, a następnie wywoływania interfejsu API. Używasz zdefiniowanych getToken wcześniej funkcji 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 opisane w artykule Zabezpieczanie ASP.NET internetowego interfejsu 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 określonym w pliku authConfig.js , upewnij się, że zaktualizujesz plik authConfig.js , aby użyć poprawnego numeru portu internetowego interfejsu API.

  2. W terminalu upewnij się, że jesteś w folderze projektu zawierającym demona Node.js aplikacji, takiej 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 uruchomione pomyślnie, w oknie konsoli powinny znajdować się dane zwrócone przez zmienną punktu końcowego todos internetowego interfejsu API, podobnie jak w poniższej tablicy 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'
}

Następny krok