Udostępnij za pośrednictwem


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

W tym samouczku pokazano, 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ć ją, aby uzyskała token dostępu potrzebny do wywoływania interfejsu programowania aplikacji internetowej. Utworzysz aplikację Node.js przy użyciu biblioteki Microsoft Authentication Library (MSAL) dla środowiska Node , aby uprościć dodawanie autoryzacji do aplikacji.

W tym samouczku:

  • Konfigurowanie ról aplikacji dla internetowego interfejsu API
  • Udzielanie uprawnień do aplikacji demona
  • 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

  • Zarejestruj nową aplikację kliencką w centrum administracyjnym firmy Microsoft, skonfigurowaną dla kont w dowolnym katalogu organizacyjnym i osobistych kontach Microsoft. Aby uzyskać więcej informacji, zobacz Rejestrowanie aplikacji . Zapisz następujące wartości na stronie Przegląd aplikacji do późniejszego użycia:
    • Identyfikator aplikacji (klienta)
    • Identyfikator katalogu (klienta)
    • Nazwa domeny katalogu (dzierżawy) (na przykład contoso.onmicrosoft.com lub contoso.com).
  • Dodaj tajny klucz klienta do rejestracji aplikacji klienckiej. Nie używaj tajnych danych klienta w aplikacjach przeznaczonych na produkcję. Zamiast tego użyj certyfikatów lub poświadczeń federacyjnych. Aby uzyskać więcej informacji, zobacz Dodawanie poświadczeń do aplikacji.
  • Chroniony internetowy interfejs API, który jest uruchomiony i gotowy do akceptowania żądań. 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żywany program Visual Studio Code.

Konfigurowanie ról aplikacji

Interfejs API musi opublikować co najmniej jedną rolę aplikacji, znaną również jako uprawnienia aplikacji , aby aplikacje klienckie mogły uzyskiwać token dostępu w swoim imieniu. Uprawnienia aplikacji to typ uprawnień, które interfejsy API powinny definiować, gdy chcą umożliwić aplikacjom klienckim pomyślne uwierzytelnienie się samodzielnie, bez konieczności logowania użytkowników. Aby opublikować zezwolenie aplikacji, wykonaj następujące kroki:

  1. Na stronie Rejestracje aplikacji wybierz utworzoną aplikację (np. ciam-ToDoList-api), aby otworzyć stronę Przegląd.

  2. W obszarze Zarządzanie wybierz pozycję Role aplikacji.

  3. Wybierz pozycję Utwórz rolę aplikacji, a następnie wprowadź następujące wartości, a następnie wybierz pozycję Zastosuj , aby zapisać zmiany:

    Majątek Wartość
    nazwa wyświetlana ToDoList.Read.All
    Dozwolone typy członków Aplikacje
    Wartość ToDoList.Read.All
    Opis Zezwól aplikacji na odczytywanie listy zadań każdego użytkownika przy użyciu "TodoListApi"
    Czy chcesz aktywować rolę tej aplikacji? Zachowaj to zaznaczone
  4. Ponownie wybierz pozycję Utwórz rolę aplikacji, a następnie wprowadź następujące wartości dla drugiej roli aplikacji, a następnie wybierz pozycję Zastosuj , aby zapisać zmiany:

    Majątek Wartość
    nazwa wyświetlana ToDoList.ReadWrite.All
    Dozwolone typy członków Aplikacje
    Wartość ToDoList.ReadWrite.All
    Opis "Zezwól aplikacji na odczytywanie i zapisywanie list zadań wszystkich użytkowników przy użyciu 'ToDoListApi'"
    Czy chcesz aktywować rolę tej aplikacji? Zachowaj to zaznaczone

Konfiguracja roszczenia tokenu idtyp

Możesz dodać opcjonalne oświadczenie idtyp, aby ułatwić API sieci Web określenie, czy token jest tokenem aplikacji , czy tokenem aplikacji + użytkownika . Mimo że w tym samym celu można użyć kombinacji oświadczeń scp i ról, użycie oświadczenia idtyp jest najprostszym sposobem na odróżnienie tokenu aplikacji od tokenu aplikacji + użytkownika. Na przykład wartość tego roszczenia to aplikacja, gdy token jest tokenem przeznaczonym wyłącznie dla aplikacji.

Nadaj uprawnienia API dla aplikacji demona

  1. Na stronie Rejestracje aplikacji wybierz utworzoną aplikację, na przykład ciam-client-app.

  2. W sekcji Zarządzanie wybierz Uprawnienia API.

  3. W obszarze Skonfigurowane uprawnienia wybierz pozycję Dodaj uprawnienie.

  4. Wybierz kartę API używane przez moją organizację.

  5. Na liście API wybierz API, takie jak ciam-ToDoList-api.

  6. Wybierz opcję Uprawnienia aplikacji. Wybieramy tę opcję, gdy aplikacja loguje się jako sama, ale nie w imieniu użytkownika.

  7. Z listy uprawnień wybierz pozycję TodoList.Read.All, ToDoList.ReadWrite.All (w razie potrzeby użyj pola wyszukiwania).

  8. Wybierz przycisk Dodaj uprawnienia.

  9. Na tym etapie poprawnie przydzieliłeś już uprawnienia. Jednak ponieważ aplikacja demona nie zezwala użytkownikom na interakcję z nią, sami użytkownicy nie mogą wyrazić zgody na te uprawnienia. Aby rozwiązać ten problem, administrator musi wyrazić zgodę na te uprawnienia w imieniu wszystkich użytkowników w dzierżawie:

    1. Wybierz pozycję <, a następnie wybierz pozycję >.
    2. Wybierz Odśwież, a następnie upewnij się, że w sekcji < dla obu uprawnień widnieje wpis Przyznane dla >nazwa twojego dzierżawcy.

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ą katalogową (dzierżawcy). Na przykład, jeśli podstawowa domena najemcy to contoso.onmicrosoft.com, użyj contoso. Jeśli nie masz nazwy najemcy, dowiedz się, jak sprawdzić szczegóły najemcy.

  • 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) aplikacji interfejsu API dla sieci, którą skopiowałeś wcześniej.

Zwróć uwagę, że scopes właściwość w zmiennej protectedResources to identyfikator zasobu (identyfikator URI identyfikatora aplikacji) internetowego interfejsu API zarejestrowanego w ramach wymagań wstępnych. 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łaj 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.

Sfinalizuj aplikację 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 opisane w samouczku Zabezpieczanie internetowego interfejsu API ASP.NET , 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