Compartilhar via


Tutorial: Chamar uma API Web a partir da sua aplicação daemon Node.js

Este tutorial demonstra como preparar o Node.js aplicação cliente daemon e, em seguida, configurá-la para adquirir um token de acesso para chamar uma API Web. A aplicação que criar utiliza a Biblioteca de Autenticação da Microsoft (MSAL) para o Node para simplificar a adição de autorização à aplicação daemon do nó.

O fluxo de concessão de credenciais de cliente OAuth 2.0 permite que um serviço Web (cliente confidencial) utilize as suas próprias credenciais, em vez de representar um utilizador, para autenticar antes de chamar outro serviço Web. O fluxo de concessão de credenciais de cliente é normalmente utilizado para interações servidor a servidor que têm de ser executadas em segundo plano, sem interação imediata com um utilizador.

Neste tutorial, irá:

  • Crie uma aplicação Node.js e, em seguida, instale dependências.
  • Ative a aplicação Node.js para adquirir um token de acesso para chamar uma API Web.

Pré-requisitos

  • Node.js.
  • Visual Studio Code ou outro editor de código.
  • Detalhes de registo da aplicação daemon Node.js e da API Web que criou no tutorial preparar inquilino.
  • Uma API Web protegida que está em execução e pronta para aceitar pedidos. Se ainda não criou uma, veja o tutorial criar uma API Web protegida. Certifique-se de que esta API Web está a utilizar os detalhes de registo de aplicações que criou no tutorial preparar inquilino. Certifique-se de que a API Web expõe os seguintes pontos finais através de https:
    • GET /api/todolist para obter todos todos.
    • POST /api/todolist para adicionar um todo.

Criar o projeto daemon Node.js

Crie uma pasta para alojar a sua aplicação daemon Node.js, como ciam-call-api-node-daemon:

  1. No terminal, altere o diretório para a pasta da aplicação Daemon no nó, como cd ciam-call-api-node-daemon, e execute npm init -y. Este comando cria um ficheiro package.json predefinido para o projeto Node.js. Este comando cria um ficheiro predefinido package.json para o projeto Node.js.

  2. Crie pastas e ficheiros adicionais para alcançar a seguinte estrutura de projeto:

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

Instalar dependências de aplicações

No terminal, instale axiosyargs e @azure/msal-node packages ao executar o seguinte comando:

npm install axios yargs @azure/msal-node   

Criar objeto de configuração MSAL

No editor de código, abra authConfig.js ficheiro e, em seguida, adicione o seguinte código:

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

O msalConfig objeto contém um conjunto de opções de configuração que utiliza para personalizar o comportamento do fluxo de autorização.

No ficheiro deauthConfig.js , substitua:

  • Enter_the_Application_Id_Here com o ID da Aplicação (cliente) da aplicação daemon cliente que registou anteriormente.

  • Enter_the_Tenant_Subdomain_Here e substitua-o pelo subdomínio Diretório (inquilino). Por exemplo, se o domínio primário do inquilino for contoso.onmicrosoft.com, utilize contoso. Se não tiver o nome do inquilino, saiba como ler os detalhes do inquilino.

  • Enter_the_Client_Secret_Here com o valor do segredo da aplicação daemon do cliente que copiou anteriormente.

  • Enter_the_Web_Api_Application_Id_Here com o ID da Aplicação (cliente) da aplicação API Web que copiou anteriormente.

Repare que a scopes propriedade na protectedResources variável é o identificador de recurso (URI do ID da aplicação) da API Web que registou anteriormente. O URI de âmbito completo é semelhante a api://Enter_the_Web_Api_Application_Id_Here/.default.

Adquirir um token de acesso

No editor de código, abra auth.js ficheiro e, em seguida, adicione o seguinte código:

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

No código:

  • Prepare o tokenRequest objeto e apiConfig . Contém tokenRequest o âmbito para o qual pede um token de acesso. O âmbito tem um aspeto semelhante api://Enter_the_Web_Api_Application_Id_Here/.defaulta . O apiConfig objeto contém o ponto final da API Web. Saiba mais sobre o fluxo de credenciais de cliente OAuth 2.0.

  • Pode criar uma instância de cliente confidencial ao transmitir o msalConfig objeto para o construtor da classe ConfidentialClientApplication .

    const cca = new msal.ConfidentialClientApplication(msalConfig);
    
  • Em seguida, utilize a função acquireTokenByClientCredential para adquirir um token de acesso. Implementa esta lógica na função getToken :

    cca.acquireTokenByClientCredential(tokenRequest);
    

Depois de adquirir um token de acesso, pode continuar a chamar uma API.

Chamar uma API

No editor de código, abra fetch.js ficheiro e, em seguida, adicione o seguinte código:

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

Neste código, vai fazer uma chamada à API Web ao transmitir o token de acesso como um token de portador no cabeçalho do pedido Authorization :

 Authorization: `Bearer ${accessToken}`

Utilize o token de acesso que adquiriu anteriormente em Adquirir um token de acesso.

Assim que a API Web receber o pedido, avalia-o e, em seguida, determina que se trata de um pedido de aplicação. Se o token de acesso for válido, a API Web devolverá os dados pedidos. Caso contrário, a API devolve um 401 Unauthorized erro HTTP.

Finalizar a aplicação daemon

No editor de código, abra index.js ficheiro e, em seguida, adicione o seguinte código:

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

Este código é o ponto de entrada da sua aplicação. Utilize a biblioteca de análise de argumentos da linha de comandos yargs js para Node.js aplicações para obter interativamente um token de acesso e, em seguida, chamar a API. Utilize as getToken funções e callApi que definiu anteriormente:

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

Executar e testar a aplicação daemon e a API

Neste momento, está pronto para testar a aplicação daemon do cliente e a API Web:

  1. Utilize os passos que aprendeu no tutorial Proteger uma API Web ASP.NET para iniciar a API Web. A sua API Web está agora pronta para servir pedidos de cliente. Se não executar a API Web na porta 44351 conforme especificado no ficheiro deauthConfig.js , certifique-se de que atualiza o ficheiro deauthConfig.js para utilizar o número de porta da API Web correto.

  2. No terminal, certifique-se de que está na pasta do projeto que contém o daemon Node.js aplicação, como ciam-call-api-node-daemon, e execute o seguinte comando:

    node . --op getToDos
    

Se a aplicação daemon e a API Web forem executadas com êxito, deverá encontrar os dados devolvidos pela variável de ponto todos final da API Web, semelhante à seguinte matriz JSON, na janela da consola:

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

Passos seguintes

Saiba como Utilizar o certificado de cliente em vez de um segredo para autenticação no seu Node.js aplicação confidencial.