Freigeben über


Tutorial: Aufrufen einer Web-API aus Ihrer Node.js-Daemonanwendung

Dieses Tutorial ist der letzte Teil einer Reihe, in der veranschaulicht wird, wie Sie Ihre Node.js-Daemonclient-App mithilfe des Flows für die Zuweisung von Clientanmeldeinformationen in OAuth 2.0 (Open Authorization) vorbereiten und anschließend so konfigurieren, dass sie ein Zugriffstoken für das Aufrufen einer Web-API abruft. In Teil 1 dieser Reihe haben Sie eine Web-API und eine Daemon-App im Microsoft Entra Admin Center registriert und Berechtigungen erteilt. In diesem letzten Schritt wird veranschaulicht, wie Sie eine Node.js-Anwendung mithilfe der Microsoft-Authentifizierungsbibliothek (Microsoft Authentication Library, MSAL) für Node erstellen, um das Hinzufügen einer Autorisierung bei Ihrer App zu vereinfachen.

In diesem Tutorial:

  • Erstellen Sie eine Node.js-App in Visual Studio Code, und installieren Sie anschließend die Abhängigkeiten.
  • Aktivieren Sie die Node.js-App, um ein Zugriffstoken zum Aufrufen einer Web-API abzurufen.

Voraussetzungen

Erstellen des Node.js-Daemonprojekts

Erstellen Sie einen Ordner zum Hosten Ihrer Node.js-Daemonanwendung, z. B. ciam-call-api-node-daemon:

  1. Wechseln Sie in Ihrem Terminal in das Verzeichnis Ihres Node.js-Daemonanwendungsordners, z. B. cd ciam-call-api-node-daemon, und führen Sie dann npm init -y aus. Dieser Befehl erstellt eine Standarddatei namens package.json für Ihr Node.js-Projekt. Mit diesem Befehl wird eine package.json-Standarddatei für Ihr Node.js-Projekt erstellt.

  2. Erstellen Sie weitere Ordner und Dateien, um die folgende Projektstruktur zu erstellen:

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

Installieren der App-Abhängigkeiten

Installieren Sie in Ihrem Terminal die Pakete axios, yargs und @azure/msal-node, indem Sie die folgenden Befehle ausführen:

npm install axios yargs @azure/msal-node   

Erstellen des MSAL-Konfigurationsobjekts

Öffnen Sie in Ihrem Code-Editor die Datei authConfig.js, und fügen Sie dann den folgenden Code hinzu:

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

Das msalConfig-Objekt enthält eine Reihe von Konfigurationsoptionen, die von Ihnen zum Anpassen des Verhaltens Ihres Autorisierungsflows verwendet werden.

Ersetzen Sie Folgendes in Ihrer authConfig.js-Datei:

  • Enter_the_Application_Id_Here mit der Anwendungs-ID (Client-ID) der zuvor von Ihnen registrierten Clientdaemon-App.

  • Enter_the_Tenant_Subdomain_Here, und ersetzen Sie ihn durch die Unterdomäne des Verzeichnisses (des Mandanten). Wenn Ihre primäre Mandantendomäne beispielsweise contoso.onmicrosoft.com lautet, verwenden Sie contoso. Wenn Sie ihren Mandantennamen nicht kennen, können Sie Ihre Mandantendetails auslesen.

  • Enter_the_Client_Secret_Here mit dem geheimen Wert der Client-Daemon-App, den Sie zuvor kopiert haben.

  • Enter_the_Web_Api_Application_Id_Here durch die Anwendungs-ID (Client-ID) der zuvor von Ihnen kopierten Web-API-App.

Beachten Sie, dass es sich bei der scopes-Eigenschaft in der protectedResources-Variablen um den Ressourcenbezeichner (Anwendungs-ID-URI) der Web-API handelt, die Sie zuvor registriert haben. Der vollständige URI des Bereichs sieht ähnlich aus wie api://Enter_the_Web_Api_Application_Id_Here/.default.

Abrufen eines Zugriffstokens

Öffnen Sie in Ihrem Code-Editor die Datei auth.js, und fügen Sie dann den folgenden Code hinzu:

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

Im Code:

  • Bereiten Sie das tokenRequest- und apiConfig-Objekt vor. Die tokenRequest enthält den Bereich, für den Sie ein Zugriffstoken anfordern. Der Bereich sieht etwa so aus wie api://Enter_the_Web_Api_Application_Id_Here/.default. Das apiConfig-Objekt enthält den Endpunkt zu Ihrer Web-API. Erfahren Sie mehr über den OAuth 2.0-Clientanmeldeinformationsflow.

  • Sie erstellen eine vertrauliche Clientinstanz, indem Sie das msalConfig-Objekt an den Konstruktor der ConfidentialClientApplication-Klasse übergeben.

    const cca = new msal.ConfidentialClientApplication(msalConfig);
    
  • Anschließend verwenden Sie die Funktion acquireTokenByClientCredential, um ein Zugriffstoken abzurufen. Sie implementieren diese Logik in der getToken-Funktion:

    cca.acquireTokenByClientCredential(tokenRequest);
    

Nachdem Sie ein Zugriffstoken abgerufen haben, können Sie mit dem Aufrufen einer API fortfahren.

Aufrufen einer API

Öffnen Sie in Ihrem Code-Editor die Datei fetch.js, und fügen Sie dann den folgenden Code hinzu:

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

In diesem Code rufen Sie die Web-API auf, indem Sie das Zugriffstoken als Bearertoken im Header der Anforderung Authorization übergeben:

 Authorization: `Bearer ${accessToken}`

Sie verwenden das Zugriffstoken, das Sie zuvor in Abrufen eines Zugriffstokens abgerufen haben.

Sobald die Web-API die Anforderung empfangen hat, wird sie ausgewertet und dann festgestellt, dass es sich um eine Anwendungsanforderung handelt. Wenn das Zugriffstoken gültig ist, gibt die Web-API angeforderte Daten zurück. Andernfalls gibt die API einen 401 Unauthorized-HTTP-Fehler zurück.

Abschließen Ihrer Daemon-App

Öffnen Sie in Ihrem Code-Editor die Datei index.js, und fügen Sie dann den folgenden Code hinzu:

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

Dieser Code ist der Einstiegspunkt für Ihre App. Sie verwenden die Bibliothek yargs JavaScript zum Analysieren von Befehlszeilenargumenten für Node.js-Apps, um interaktiv ein Zugriffstoken abzurufen und dann die API aufzurufen. Sie verwenden die Funktionen getToken und callApi, die Sie zuvor definiert haben:

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

Ausführen und Testen der Daemon-App und API

An diesem Punkt können Sie Ihre Clientdaemon-App und Web-API testen:

  1. Verwenden Sie die Schritte, die Sie im Tutorial Schützen einer ASP.NET-Web-API kennengelernt haben, um Ihre Web-API zu starten. Ihre Web-API ist jetzt bereit, Clientanforderungen zu bedienen. Wenn Sie Ihre Web-API nicht an Port 44351 ausführen, wie in der Datei authConfig.js angegeben, stellen Sie sicher, dass Sie die Datei authConfig.js aktualisieren, um die korrekte Portnummer Ihrer Web-API zu verwenden.

  2. Vergewissern Sie sich in Ihrem Terminal, dass Sie sich in dem Projektordner befinden, der Ihre Node.js-Daemon-App enthält, z. B. ciam-call-api-node-daemon, und führen Sie dann den folgenden Befehl aus:

    node . --op getToDos
    

Wenn Ihre Daemon-App und Ihre Web-API erfolgreich ausgeführt werden, sollten im Konsolenfenster die von der Variablen todos des Web-API-Endpunkts zurückgegebenen Daten ähnlich dem folgenden JSON-Array angezeigt werden:

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

Nächster Schritt