Compartilhar via


Habilitar a autenticação em seu próprio aplicativo Angular usando o Azure Active Directory B2C

Importante

A partir de 1º de maio de 2025, o Azure AD B2C não estará mais disponível para compra para novos clientes. Saiba mais em nossas perguntas frequentes.

Este artigo mostra como adicionar a autenticação do Azure AD B2C (Azure Active Directory B2C) ao seu próprio SPA (aplicativo de página única) Angular. Saiba como integrar um aplicativo Angular à biblioteca de autenticação MSAL for Angular .

Use este artigo com o artigo relacionado intitulado Configurar autenticação em um aplicativo de página única angular de exemplo. Substitua o aplicativo Angular de exemplo pelo seu próprio aplicativo Angular. Depois de concluir as etapas neste artigo, seu aplicativo aceitará entradas por meio do Azure AD B2C.

Pré-requisitos

Conclua as etapas no artigo Configurar autenticação em um aplicativo de página única Angular de exemplo.

Criar um projeto de aplicativo Angular

Você pode usar um projeto de aplicativo Angular existente ou criar um novo. Para criar um novo projeto, execute os comandos a seguir.

Os comandos:

  1. Instale a CLI angular usando o gerenciador de pacotes npm.
  2. Crie um espaço de trabalho Angular com um módulo de roteamento. O nome do aplicativo é msal-angular-tutorial. Você pode alterá-lo para qualquer nome de aplicativo Angular válido, como contoso-car-service.
  3. Vá para a pasta do aplicativo.
npm install -g @angular/cli 
ng new msal-angular-tutorial --routing=true --style=css --strict=false
cd msal-angular-tutorial

Instalar as dependências

Para instalar as bibliotecas MSAL Browser e MSAL Angular em seu aplicativo, execute o seguinte comando no shell de comando:

npm install @azure/msal-browser @azure/msal-angular

Instalar a biblioteca de componentes do Material Angular (opcional, para interface do usuário):

npm install @angular/material @angular/cdk

Adicionar os componentes de autenticação

O código de exemplo consiste nos seguintes componentes:

Componente Tipo Descrição
auth-config.ts Constantes Esse arquivo de configuração contém informações sobre o provedor de identidade do Azure AD B2C e o serviço de API Web. O aplicativo Angular usa essas informações para estabelecer uma relação de confiança com o Azure AD B2C, entrar e sair do usuário, adquirir tokens e validar os tokens.
app.module.ts Módulo Angular Este componente descreve como as partes do aplicativo se encaixam. Este é o módulo raiz usado para inicializar e abrir o aplicativo. Neste passo a passo, você adiciona alguns componentes ao módulo app.module.ts e inicia a biblioteca MSAL com o objeto de configuração MSAL.
app-routing.module.ts Módulo de roteamento angular Esse componente habilita a navegação interpretando uma URL do navegador e carregando o componente correspondente. Neste passo a passo, você adiciona alguns componentes ao módulo de roteamento e protege os componentes com o MSAL Guard. Somente usuários autorizados podem acessar os componentes protegidos.
app.component.* Componente angular O ng new comando criou um projeto Angular com um componente raiz. Neste passo a passo, você altera o componente do aplicativo para hospedar a barra de navegação superior. A barra de navegação contém vários botões, incluindo botões de entrada e saída. A app.component.ts classe manipula os eventos de entrada e saída.
home.component.* Componente angular Neste passo a passo, você adiciona o componente inicial para renderizar a home page para acesso anônimo. Esse componente demonstra como verificar se um usuário entrou.
profile.component.* Componente angular Neste passo a passo, você adiciona o componente profile para aprender a ler as informações contidas no token de ID.
webapi.component.* Componente angular Neste passo a passo, você adiciona o componente webapi para saber como chamar uma API Web.

Para adicionar os seguintes componentes ao seu aplicativo, execute os seguintes comandos da CLI angular. Os comandos generate component:

  1. Crie uma pasta para cada componente. A pasta contém os arquivos TypeScript, HTML, CSS e test.
  2. Atualize os arquivos app.module.ts e app-routing.module.ts com referências aos novos componentes.
ng generate component home
ng generate component profile
ng generate component webapi

Adicionar as configurações do aplicativo

As configurações do provedor de identidade do Azure AD B2C e da API Web são armazenadas no arquivo auth-config.ts . Na pasta src/app , crie um arquivo chamado auth-config.ts que contenha o código a seguir. Em seguida, altere as configurações conforme descrito em 3.1 Configurar o exemplo angular.

import { LogLevel, Configuration, BrowserCacheLocation } from '@azure/msal-browser';

const isIE = window.navigator.userAgent.indexOf("MSIE ") > -1 || window.navigator.userAgent.indexOf("Trident/") > -1;
 
export const b2cPolicies = {
     names: {
         signUpSignIn: "b2c_1_susi_reset_v2",
         editProfile: "b2c_1_edit_profile_v2"
     },
     authorities: {
         signUpSignIn: {
             authority: "https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/b2c_1_susi_reset_v2",
         },
         editProfile: {
             authority: "https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/b2c_1_edit_profile_v2"
         }
     },
     authorityDomain: "your-tenant-name.b2clogin.com"
 };
 
 
export const msalConfig: Configuration = {
     auth: {
         clientId: '<your-MyApp-application-ID>',
         authority: b2cPolicies.authorities.signUpSignIn.authority,
         knownAuthorities: [b2cPolicies.authorityDomain],
         redirectUri: '/', 
     },
     cache: {
         cacheLocation: BrowserCacheLocation.LocalStorage,
         storeAuthStateInCookie: isIE, 
     },
     system: {
         loggerOptions: {
            loggerCallback: (logLevel, message, containsPii) => {
                console.log(message);
             },
             logLevel: LogLevel.Verbose,
             piiLoggingEnabled: false
         }
     }
 }

export const protectedResources = {
  todoListApi: {
    endpoint: "http://localhost:5000/api/todolist",
    scopes: ["https://your-tenant-name.onmicrosoft.com/api/tasks.read"],
  },
}
export const loginRequest = {
  scopes: []
};

Iniciar as bibliotecas de autenticação

Aplicativos cliente públicos não são confiáveis para manter com segurança os segredos do aplicativo, portanto, eles não têm segredos do cliente. Na pasta src/app , abra app.module.ts e faça as seguintes alterações:

  1. Importe as bibliotecas MSAL Angular e MSAL Browser.
  2. Importe o módulo de configuração do Azure AD B2C.
  3. Importe HttpClientModule. O cliente HTTP é usado para chamar APIs Web.
  4. Importe o interceptador HTTP Angular. A MSAL usa o Interceptor para injetar o token de portador no cabeçalho de autorização HTTP.
  5. Adicione os materiais Angular essenciais.
  6. Crie uma instância de MSAL usando um objeto de aplicativo de cliente público de várias contas. A inicialização do MSAL inclui a passagem:
    1. O objeto de configuração para auth-config.ts.
    2. O objeto de configuração para a proteção de roteamento.
    3. O objeto de configuração do interceptador MSAL. A classe interceptor adquire automaticamente tokens para solicitações de saída que usam a classe HttpClient Angular para recursos protegidos conhecidos.
  7. Configure o HTTP_INTERCEPTORS e MsalGuardprovedores do Angular .
  8. Adicione MsalRedirectComponent ao Angular Bootstrap.

Na pasta src/app , edite app.module.ts e faça as modificações mostradas no snippet de código a seguir. As alterações são sinalizadas com "As alterações começam aqui" e "As alterações terminam aqui".

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

/* Changes start here. */
// Import MSAL and MSAL browser libraries. 
import { MsalGuard, MsalInterceptor, MsalModule, MsalRedirectComponent } from '@azure/msal-angular';
import { InteractionType, PublicClientApplication } from '@azure/msal-browser';

// Import the Azure AD B2C configuration 
import { msalConfig, protectedResources } from './auth-config';

// Import the Angular HTTP interceptor. 
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { ProfileComponent } from './profile/profile.component';
import { HomeComponent } from './home/home.component';
import { WebapiComponent } from './webapi/webapi.component';

// Add the essential Angular materials.
import { MatButtonModule } from '@angular/material/button';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatListModule } from '@angular/material/list';
import { MatTableModule } from '@angular/material/table';
/* Changes end here. */

@NgModule({
  declarations: [
    AppComponent,
    ProfileComponent,
    HomeComponent,
    WebapiComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    /* Changes start here. */
    // Import the following Angular materials. 
    MatButtonModule,
    MatToolbarModule,
    MatListModule,
    MatTableModule,
    // Import the HTTP client. 
    HttpClientModule,

    // Initiate the MSAL library with the MSAL configuration object
    MsalModule.forRoot(new PublicClientApplication(msalConfig),
      {
        // The routing guard configuration. 
        interactionType: InteractionType.Redirect,
        authRequest: {
          scopes: protectedResources.todoListApi.scopes
        }
      },
      {
        // MSAL interceptor configuration.
        // The protected resource mapping maps your web API with the corresponding app scopes. If your code needs to call another web API, add the URI mapping here.
        interactionType: InteractionType.Redirect,
        protectedResourceMap: new Map([
          [protectedResources.todoListApi.endpoint, protectedResources.todoListApi.scopes]
        ])
      })
    /* Changes end here. */
  ],
  providers: [
    /* Changes start here. */
    {
      provide: HTTP_INTERCEPTORS,
      useClass: MsalInterceptor,
      multi: true
    },
    MsalGuard
    /* Changes end here. */
  ],
  bootstrap: [
    AppComponent,
    /* Changes start here. */
    MsalRedirectComponent
    /* Changes end here. */
  ]
})
export class AppModule { }

Configurar rotas

Nesta seção, configure as rotas para seu aplicativo Angular. Quando um usuário seleciona um link na página para se mover dentro de seu aplicativo de página única ou insere uma URL na barra de endereços, as rotas mapeiam a URL para um componente Angular. A interface canActivate de roteamento angular usa o MSAL Guard para verificar se o usuário está conectado. Se o usuário não estiver conectado, a MSAL levará o usuário para o Azure AD B2C para autenticar.

Na pasta src/app , edite app-routing.module.ts fazer as modificações mostradas no snippet de código a seguir. As alterações são sinalizadas com "As alterações começam aqui" e "As alterações terminam aqui".

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { MsalGuard } from '@azure/msal-angular';
import { HomeComponent } from './home/home.component';
import { ProfileComponent } from './profile/profile.component';
import { WebapiComponent } from './webapi/webapi.component';

const routes: Routes = [
  /* Changes start here. */
  {
    path: 'profile',
    component: ProfileComponent,
    // The profile component is protected with MSAL Guard.
    canActivate: [MsalGuard]
  },
  {
    path: 'webapi',
    component: WebapiComponent,
    // The profile component is protected with MSAL Guard.
    canActivate: [MsalGuard]
  },
  {
    // The home component allows anonymous access
    path: '',
    component: HomeComponent
  }
  /* Changes end here. */
];


@NgModule({
  /* Changes start here. */
  // Replace the following line with the next one
  //imports: [RouterModule.forRoot(routes)],
  imports: [RouterModule.forRoot(routes, {
    initialNavigation:'enabled'
  })],
  /* Changes end here. */
  exports: [RouterModule]
})
export class AppRoutingModule { }

Adicionar os botões de entrada e saída

Nesta seção, você adicionará os botões de entrada e saída ao componente do aplicativo . Na pasta src/app , abra o arquivo app.component.ts e faça as seguintes alterações:

  1. Importe os componentes necessários.

  2. Altere a classe para implementar o método OnInit. O método OnInit inscreve-se no evento observável MSAL MsalBroadcastServiceinProgress$. Use esse evento para saber o status das interações do usuário, especialmente para verificar se as interações foram concluídas.

    Antes das interações com o objeto da conta MSAL, verifique se a InteractionStatus propriedade retorna InteractionStatus.None. O subscribe evento chama o setLoginDisplay método para verificar se o usuário está autenticado.

  3. Adicionar variáveis de classe.

  4. Adicione o método login que inicia o fluxo de autorização.

  5. Adicione o método logout que desconecta o usuário.

  6. Adicione o setLoginDisplay método que verifica se o usuário está autenticado.

  7. Adicione o método ngOnDestroy para limpar o inProgress$ evento de assinatura.

Após as alterações, seu código deve se parecer com o seguinte trecho de código:

import { Component, OnInit, Inject } from '@angular/core';
import { MsalService, MsalBroadcastService, MSAL_GUARD_CONFIG, MsalGuardConfiguration } from '@azure/msal-angular';
import { InteractionStatus, RedirectRequest } from '@azure/msal-browser';
import { Subject } from 'rxjs';
import { filter, takeUntil } from 'rxjs/operators';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

/* Changes start here. */
export class AppComponent implements OnInit{
  title = 'msal-angular-tutorial';
  loginDisplay = false;
  private readonly _destroying$ = new Subject<void>();

  constructor(@Inject(MSAL_GUARD_CONFIG) private msalGuardConfig: MsalGuardConfiguration, private broadcastService: MsalBroadcastService, private authService: MsalService) { }

  ngOnInit() {

    this.broadcastService.inProgress$
    .pipe(
      filter((status: InteractionStatus) => status === InteractionStatus.None),
      takeUntil(this._destroying$)
    )
    .subscribe(() => {
      this.setLoginDisplay();
    })
  }

  login() {
    if (this.msalGuardConfig.authRequest){
      this.authService.loginRedirect({...this.msalGuardConfig.authRequest} as RedirectRequest);
    } else {
      this.authService.loginRedirect();
    }
  }

  logout() { 
    this.authService.logoutRedirect({
      postLogoutRedirectUri: 'http://localhost:4200'
    });
  }

  setLoginDisplay() {
    this.loginDisplay = this.authService.instance.getAllAccounts().length > 0;
  }

  ngOnDestroy(): void {
    this._destroying$.next(undefined);
    this._destroying$.complete();
  }
  /* Changes end here. */
}

Na pasta src/app , editeapp.component.html e faça as seguintes alterações:

  1. Adicione um link aos componentes do perfil e da API Web.
  2. Adicione o botão de login com o atributo de evento clique definido pelo método login(). Esse botão só aparecerá se a variável de classe loginDisplay for false.
  3. Adicione o botão de logout com o atributo de evento de clique definido como o método logout(). Esse botão só aparecerá se a variável de classe loginDisplay for true.
  4. Adicione um elemento de saída de roteador .

Após as alterações, seu código deve se parecer com o seguinte trecho de código:

<mat-toolbar color="primary">
  <a class="title" href="/">{{ title }}</a>

  <div class="toolbar-spacer"></div>

  <a mat-button [routerLink]="['profile']">Profile</a>
  <a mat-button [routerLink]="['webapi']">Web API</a>

  <button mat-raised-button *ngIf="!loginDisplay" (click)="login()">Login</button>
  <button mat-raised-button *ngIf="loginDisplay" (click)="logout()">Logout</button>

</mat-toolbar>
<div class="container">
  <router-outlet></router-outlet>
</div>

Opcionalmente, atualize o arquivo app.component.css com o seguinte snippet de código CSS:

.toolbar-spacer {
    flex: 1 1 auto;
  }

  a.title {
    color: white;
  }

Manipular os redirecionamentos do aplicativo

Ao usar redirecionamentos com a MSAL, você deve adicionar a diretiva app-redirect a index.html. Na pasta src, edite index.html conforme mostrado no seguinte trecho de código:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>MsalAngularTutorial</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root></app-root>
  <!-- Changes start here -->
  <app-redirect></app-redirect>
  <!-- Changes end here -->
</body>
</html>

Definir O CSS do aplicativo (opcional)

Na pasta /src , atualize o arquivo styles.css com o seguinte snippet de código CSS:

@import '~@angular/material/prebuilt-themes/deeppurple-amber.css';

html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
.container { margin: 1%; }

Dica

Neste ponto, você pode executar seu aplicativo e testar a experiência de entrada. Para executar seu aplicativo, consulte a seção Executar o aplicativo Angular .

Verificar se um usuário está autenticado

O arquivo home.component demonstra como verificar se o usuário está autenticado. Na pasta src/app/home , atualize home.component.ts com o snippet de código a seguir.

O código:

  1. Assina os evento observáveis e msalSubject$ do inProgress$.
  2. Garante que o msalSubject$ evento grave o resultado da autenticação no console do navegador.
  3. Garante que o inProgress$ evento verifique se um usuário está autenticado. O getAllAccounts() método retorna um ou mais objetos.
import { Component, OnInit } from '@angular/core';
import { MsalBroadcastService, MsalService } from '@azure/msal-angular';
import { EventMessage, EventType, InteractionStatus } from '@azure/msal-browser';
import { filter } from 'rxjs/operators';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
  loginDisplay = false;

  constructor(private authService: MsalService, private msalBroadcastService: MsalBroadcastService) { }

  ngOnInit(): void {
    this.msalBroadcastService.msalSubject$
      .pipe(
        filter((msg: EventMessage) => msg.eventType === EventType.LOGIN_SUCCESS),
      )
      .subscribe((result: EventMessage) => {
        console.log(result);
      });

    this.msalBroadcastService.inProgress$
      .pipe(
        filter((status: InteractionStatus) => status === InteractionStatus.None)
      )
      .subscribe(() => {
        this.setLoginDisplay();
      })
  }

  setLoginDisplay() {
    this.loginDisplay = this.authService.instance.getAllAccounts().length > 0;
  }
}

Na pasta src/app/home , atualize home.component.html com o snippet HTML a seguir. A diretiva *ngIf verifica a loginDisplay variável de classe para mostrar ou ocultar as mensagens de boas-vindas.

<div *ngIf="!loginDisplay">
    <p>Please sign-in to see your profile information.</p>
</div>

<div *ngIf="loginDisplay">
    <p>Login successful!</p>
    <p>Request your profile information by clicking Profile above.</p>
</div>

Ler as declarações de token de ID

O arquivo profile.component demonstra como acessar as declarações de token de ID do usuário. Na pasta src/app/profile , atualize profile.component.ts com o snippet de código a seguir.

O código:

  1. Importa os componentes necessários.
  2. Assina o evento observável do inProgress$. O evento carrega a conta e lê as declarações do token de ID.
  3. Garante que o checkAndSetActiveAccount método verifique e defina a conta ativa. Essa ação é comum quando o aplicativo interage com vários fluxos de usuário do Azure AD B2C ou políticas personalizadas.
  4. Certifique-se de que o método getClaims obtém as declarações de token de ID do objeto de conta MSAL ativo. Em seguida, o método adiciona as declarações à dataSource matriz. A matriz é renderizada para o usuário com a associação de modelo do componente.
import { Component, OnInit } from '@angular/core';
import { MsalBroadcastService, MsalService } from '@azure/msal-angular';
import { EventMessage, EventType, InteractionStatus } from '@azure/msal-browser';
import { Subject } from 'rxjs';
import { filter, takeUntil } from 'rxjs/operators';

@Component({
  selector: 'app-profile',
  templateUrl: './profile.component.html',
  styleUrls: ['./profile.component.css']
})

export class ProfileComponent implements OnInit {
  displayedColumns: string[] = ['claim', 'value'];
  dataSource: Claim[] = [];
  private readonly _destroying$ = new Subject<void>();
  
  constructor(private authService: MsalService, private msalBroadcastService: MsalBroadcastService) { }

  ngOnInit(): void {

    this.msalBroadcastService.inProgress$
      .pipe(
        filter((status: InteractionStatus) =>  status === InteractionStatus.None || status === InteractionStatus.HandleRedirect),
        takeUntil(this._destroying$)
      )
      .subscribe(() => {
        this.checkAndSetActiveAccount();
        this.getClaims(this.authService.instance.getActiveAccount()?.idTokenClaims)
      })
  }

  checkAndSetActiveAccount() {

    let activeAccount = this.authService.instance.getActiveAccount();

    if (!activeAccount && this.authService.instance.getAllAccounts().length > 0) {
      let accounts = this.authService.instance.getAllAccounts();
      this.authService.instance.setActiveAccount(accounts[0]);
    }
  }

  getClaims(claims: any) {

    let list: Claim[]  =  new Array<Claim>();

    Object.keys(claims).forEach(function(k, v){
      
      let c = new Claim()
      c.id = v;
      c.claim = k;
      c.value =  claims ? claims[k]: null;
      list.push(c);
    });
    this.dataSource = list;

  }

  ngOnDestroy(): void {
    this._destroying$.next(undefined);
    this._destroying$.complete();
  }
}

export class Claim {
  id: number;
  claim: string;
  value: string;
}

Na pasta src/app/profile , atualize profile.component.html com o seguinte snippet HTML:

<h1>ID token claims:</h1>

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">

  <!-- Claim Column -->
  <ng-container matColumnDef="claim">
    <th mat-header-cell *matHeaderCellDef> Claim </th>
    <td mat-cell *matCellDef="let element"> {{element.claim}} </td>
  </ng-container>

  <!-- Value Column -->
  <ng-container matColumnDef="value">
    <th mat-header-cell *matHeaderCellDef> Value </th>
    <td mat-cell *matCellDef="let element"> {{element.value}} </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

Chamar uma API da Web

Para chamar uma API Web de autorização baseada em token, o aplicativo precisa ter um token de acesso válido. O provedor MsalInterceptor adquire automaticamente tokens para solicitações de saída que usam a classe HttpClient Angular para recursos protegidos conhecidos.

Importante

O método de inicialização MSAL (na app.module.ts classe) mapeia recursos protegidos, como APIs Web, com os escopos de aplicativo necessários usando o protectedResourceMap objeto. Se o código precisar chamar outra API Web, adicione o URI da API Web e o método HTTP da API Web, com os escopos correspondentes, ao protectedResourceMap objeto. Para obter mais informações, consulte Mapa de Recursos Protegidos.

Quando o objeto HttpClient chama uma API Web, o provedor MsalInterceptor executa as seguintes etapas:

  1. Adquire um token de acesso com as permissões necessárias (escopos) para o ponto de extremidade da API Web.

  2. Passa o token de acesso como um token de portador no cabeçalho de autorização da solicitação HTTP usando este formato:

    Authorization: Bearer <access-token>
    

O arquivo webapi.component demonstra como chamar uma API Web. Na pasta src/app/webapi , atualize webapi.component.ts com o snippet de código a seguir.

O código:

  1. Usa a classe HttpClient Angular para chamar a API Web.
  2. Lê o elemento auth-config da classe protectedResources.todoListApi.endpoint. Esse elemento especifica o URI da API Web. Baseando-se no URI da API Web, o interceptador MSAL obtém um token de acesso com os escopos correspondentes.
  3. Obtém o perfil da API Web e define a profile variável de classe.
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { protectedResources } from '../auth-config';

type ProfileType = {
  name?: string
};

@Component({
  selector: 'app-webapi',
  templateUrl: './webapi.component.html',
  styleUrls: ['./webapi.component.css']
})
export class WebapiComponent implements OnInit {
  todoListEndpoint: string = protectedResources.todoListApi.endpoint;
  profile!: ProfileType;

  constructor(
    private http: HttpClient
  ) { }

  ngOnInit() {
    this.getProfile();
  }

  getProfile() {
    this.http.get(this.todoListEndpoint)
      .subscribe(profile => {
        this.profile = profile;
      });
  }
}

Na pasta src/app/webapi , atualize webapi.component.html com o snippet HTML a seguir. O modelo do componente renderiza o nome que a API Web retorna. Na parte inferior da página, o modelo renderiza o endereço da API Web.

<h1>The web API returns:</h1>
<div>
    <p><strong>Name: </strong> {{profile?.name}}</p>
</div>

<div class="footer-text">
    Web API: {{todoListEndpoint}}
</div>

Opcionalmente, atualize o arquivo webapi.component.css com o seguinte snippet de código CSS:

.footer-text {
    position: absolute;
    bottom: 50px;
    color: gray;
}

Executar o aplicativo Angular

Execute o comando a seguir:

npm start

A janela do console exibe o número da porta em que o aplicativo está hospedado.

Listening on port 4200...

Dica

Como alternativa, para executar o npm start comando, use o depurador do Visual Studio Code. O depurador ajuda a acelerar seu ciclo de edição, compilação e depuração.

http://localhost:4200 Acesse o navegador para exibir o aplicativo.

Próximas etapas