Поделиться через


Включение проверки подлинности в собственном приложении Angular с помощью Azure Active Directory B2C

Это важно

Начиная с 1 мая 2025 г. Azure AD B2C больше не будет доступен для приобретения для новых клиентов. Дополнительные сведения см. в разделе "Вопросы и ответы".

В этой статье показано, как добавить аутентификацию Azure Active Directory B2C (Azure AD B2C) в собственное одностраничное приложение Angular (SPA). Узнайте, как интегрировать приложение Angular с библиотекой проверки подлинности MSAL для Angular .

Используйте эту статью с соответствующей статьей, озаглавленной "Настройка проверки подлинности в примере одностраничного приложения на Angular". Замените пример приложения Angular собственным приложением Angular. После выполнения действий, описанных в этой статье, приложение будет принимать входы через Azure AD B2C.

Предпосылки

Выполните действия, описанные в статье "Настройка проверки подлинности" в примере одностраничного приложения Angular .

Создание проекта приложения Angular

Вы можете использовать существующий проект приложения Angular или создать новый. Чтобы создать проект, выполните следующие команды.

Команды:

  1. Установите Angular CLI с помощью диспетчера пакетов npm.
  2. Создайте рабочую область Angular с модулем маршрутизации. Имя приложения — msal-angular-tutorial. Его можно изменить на любое допустимое имя приложения Angular, например contoso-car-service.
  3. Перейдите в папку каталога приложения.
npm install -g @angular/cli 
ng new msal-angular-tutorial --routing=true --style=css --strict=false
cd msal-angular-tutorial

Установка зависимостей

Чтобы установить библиотеки MSAL Browser и MSAL Angular в приложении, выполните следующую команду в командной оболочке:

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

Установите библиотеку компонентов Angular Material (необязательно, для пользовательского интерфейса):

npm install @angular/material @angular/cdk

Добавление компонентов проверки подлинности

Пример кода состоит из следующих компонентов:

Компонент Тип Описание
auth-config.ts Константы Этот файл конфигурации содержит сведения о поставщике удостоверений Azure AD B2C и веб-службе API. Приложение Angular использует эти сведения для установления отношения доверия с Azure AD B2C, входа и выхода пользователя, получения маркеров и проверки маркеров.
app.module.ts Модуль Angular Этот компонент описывает, как части приложения соответствуют друг другу. Это корневой модуль, используемый для начальной загрузки и открытия приложения. В этом пошаговом руководстве вы добавите некоторые компоненты в модуль app.module.ts и запустите библиотеку MSAL с объектом конфигурации MSAL.
app-routing.module.ts Модуль маршрутизации Angular Этот компонент обеспечивает навигацию, интерпретируя URL-адрес браузера и загружая соответствующий компонент. В этом пошаговом руководстве вы добавите некоторые компоненты в модуль маршрутизации и защищаете компоненты с помощью MSAL Guard. Доступ к защищенным компонентам может получить только авторизованные пользователи.
app.component.* Компонент Angular Команда ng new создала проект Angular с корневым компонентом. В этом пошаговом руководстве вы измените компонент приложения на размещение верхней панели навигации. Панель навигации содержит различные кнопки, включая кнопки входа и выхода. Класс app.component.ts обрабатывает события входа и выхода.
home.component.* Компонент Angular В этом пошаговом руководстве вы добавите домашний компонент, чтобы отобразить домашнюю страницу для анонимного доступа. Этот компонент демонстрирует, как проверить, выполнил ли пользователь вход.
профиль.компонент.* Компонент Angular В этом пошаговом руководстве вы добавите компонент профиля, чтобы узнать, как считывать утверждения токена идентификатора.
webapi.component.* Компонент Angular В этом пошаговом руководстве вы добавите компонент webapi , чтобы узнать, как вызвать веб-API.

Чтобы добавить в приложение следующие компоненты, выполните следующие команды Angular CLI. Команды generate component :

  1. Создайте папку для каждого компонента. Папка содержит файлы TypeScript, HTML, CSS и тестовые файлы.
  2. Обновите файлы app.module.ts и app-routing.module.ts с указанием ссылок на новые компоненты.
ng generate component home
ng generate component profile
ng generate component webapi

Добавление параметров приложения

Параметры поставщика удостоверений Azure AD B2C и веб-API хранятся в файле auth-config.ts . В папке src/app создайте файл с именем auth-config.ts , содержащий следующий код. Затем измените параметры в соответствии с описанием в 3.1 Настройка примера 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: []
};

Запуск библиотек проверки подлинности

Общедоступные клиентские приложения не являются доверенными для безопасного хранения секретов приложений, поэтому у них нет секретов клиента. В папке src/app откройте app.module.ts и внесите следующие изменения:

  1. Импортируйте библиотеки MSAL Angular и MSAL Browser.
  2. Импортируйте модуль конфигурации Azure AD B2C.
  3. Импорт HttpClientModule. HTTP-клиент используется для вызова веб-API.
  4. Импортируйте перехватчик HTTP Angular. MSAL использует перехватчик для внедрения токена типа bearer в заголовок авторизации HTTP.
  5. Добавьте необходимые компоненты Angular.
  6. Создайте экземпляр MSAL, используя объект публичного клиентского приложения для нескольких учетных записей. Инициализация MSAL включает передачу:
    1. Объект конфигурации для auth-config.ts.
    2. Объект конфигурации для защиты маршрутизации.
    3. Объект конфигурации для перехватчика MSAL. Класс перехватчика автоматически получает маркеры для исходящих запросов, использующих класс Angular HttpClient для известных защищенных ресурсов.
  7. Настройте HTTP_INTERCEPTORSMsalGuardпоставщиков Angular.
  8. Добавьте MsalRedirectComponent в начальную загрузку Angular.

В папке src/app измените app.module.ts и внесите изменения, показанные в следующем фрагменте кода. Изменения помечены как "Изменения начинаются здесь" и "Изменения заканчиваются здесь".

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

Настройка маршрутов

В этом разделе настройте маршруты для приложения Angular. Когда пользователь выбирает ссылку на странице для перемещения внутри одностраничного приложения или вводит URL-адрес в адресной строке, маршруты сопоставляют URL-адрес с компонентом Angular. Интерфейс Angular маршрутизации canActivate использует MSAL Guard для проверки того, выполнен ли вход пользователем. Если пользователь не вошел в систему, MSAL принимает пользователя в Azure AD B2C для проверки подлинности.

В папке src/app отредактируйте app-routing.module.ts, чтобы внести изменения, показанные в следующем фрагменте кода. Изменения помечены как "Изменения начинаются здесь" и "Изменения заканчиваются здесь".

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

Добавление кнопок входа и выхода

В этом разделе вы добавите кнопки входа и выхода в компонент приложения . В папке src/app откройте файл app.component.ts и внесите следующие изменения:

  1. Импорт обязательных компонентов.

  2. Измените класс, чтобы реализовать метод OnInit. Метод OnInit подписывается на наблюдаемое событие MSAL MsalBroadcastServiceinProgress$ . Используйте это событие для получения сведений о состоянии взаимодействия с пользователем, особенно для проверки завершения взаимодействия.

    Перед взаимодействием с объектом учетной записи MSAL убедитесь, что InteractionStatus свойство возвращается InteractionStatus.None. Событие subscribe вызывает setLoginDisplay метод, чтобы проверить, прошел ли пользователь проверку подлинности.

  3. Добавьте переменные класса.

  4. login Добавьте метод, который запускает поток авторизации.

  5. logout Добавьте метод, который выпишет пользователя.

  6. setLoginDisplay Добавьте метод, который проверяет, прошел ли пользователь проверку подлинности.

  7. Добавьте метод ngOnDestroy для очистки inProgress$ подписки.

После внесения изменений код должен выглядеть следующим фрагментом кода:

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. */
}

В папке src/app отредактируйте app.component.html и внесите следующие изменения:

  1. Добавьте ссылку на компоненты профиля и веб-API.
  2. Добавьте кнопку входа с атрибутом события щелчка, заданным методом login() . Эта кнопка отображается только в том случае, loginDisplay если переменная класса имеет значение false.
  3. Добавьте кнопку выхода с атрибутом события щелчка, заданным методом logout() . Эта кнопка отображается только в том случае, loginDisplay если переменная класса имеет значение true.
  4. Добавьте элемент маршрутизатора-выход .

После внесения изменений код должен выглядеть следующим фрагментом кода:

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

При необходимости обновите файл app.component.css следующим фрагментом КОДА CSS:

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

  a.title {
    color: white;
  }

Обработка перенаправлений приложений

При использовании переадресации с MSAL необходимо добавить директиву app-redirect в index.html. В папке src измените index.html , как показано в следующем фрагменте кода:

<!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>

Настройка CSS приложения (необязательно)

В папке /src обновите файл styles.css с помощью следующего фрагмента 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%; }

Подсказка

На этом этапе вы можете запустить приложение и проверить интерфейс входа. Сведения о запуске приложения см. в разделе "Запуск приложения Angular ".

Проверка подлинности пользователя

Файл home.component демонстрирует, как проверить, прошел ли пользователь проверку подлинности. В папке src/app/home обновите home.component.ts со следующим фрагментом кода.

Код:

  1. Подписывается на MSAL MsalBroadcastServicemsalSubject$ и inProgress$ наблюдаемые события.
  2. Гарантирует, что msalSubject$ событие записывает результат проверки подлинности в консоль браузера.
  3. Гарантирует, что событие проверяет, inProgress$ прошел ли пользователь проверку подлинности. Метод getAllAccounts() возвращает один или несколько объектов.
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;
  }
}

В папке src/app/home обновите home.component.html следующим фрагментом HTML. Директива *ngIf проверяет loginDisplay переменную класса, чтобы показать или скрыть приветственные сообщения.

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

Чтение утверждений маркера идентификатора

Файл profile.component демонстрирует, как получить доступ к утверждениям маркера идентификатора пользователя. В папке src/app/profile обновите profile.component.ts со следующим фрагментом кода.

Код:

  1. Импортирует необходимые компоненты.
  2. Подписывается на наблюдаемое событие MSAL MsalBroadcastServiceinProgress$ . Событие загружает учетную запись и считывает утверждения маркера идентификатора.
  3. Гарантирует, что checkAndSetActiveAccount метод проверяет и задает активную учетную запись. Это действие часто возникает при взаимодействии приложения с несколькими потоками пользователей Azure AD B2C или пользовательскими политиками.
  4. Гарантирует, что getClaims метод получает утверждения токена идентификатора из активной учетной записи MSAL. Затем метод добавляет утверждения в dataSource массив. Массив отображается пользователю посредством привязки шаблона компонента.
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;
}

В папке src/app/profile обновите profile.component.html следующим фрагментом 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>

Вызов веб-API

Чтобы вызвать веб-API авторизации на основе маркеров, приложение должно иметь действительный маркер доступа. Поставщик MsalInterceptor автоматически получает маркеры для исходящих запросов, использующих класс Angular HttpClient для известных защищенных ресурсов.

Это важно

Метод инициализации MSAL (в app.module.ts классе) сопоставляет защищенные ресурсы, такие как веб-API, с необходимыми областями приложения с помощью protectedResourceMap объекта. Если коду нужно вызвать другой веб-API, добавьте URI веб-API и метод HTTP веб-API с соответствующими областями в protectedResourceMap объект. Дополнительные сведения см. в разделе "Карта защищенных ресурсов".

Когда объект HttpClient вызывает веб-API, поставщик MsalInterceptor выполняет следующие действия:

  1. Получает токен доступа с необходимыми разрешениями (областями) для конечной точки веб-API.

  2. Передает токен доступа в качестве bearer-токена в заголовке HTTP-запроса на авторизацию с использованием этого формата:

    Authorization: Bearer <access-token>
    

Файл webapi.component демонстрирует вызов веб-API. В папке src/app/webapi обновите webapi.component.ts со следующим фрагментом кода.

Код:

  1. Использует класс Angular HttpClient для вызова веб-API.
  2. Считывает элемент auth-config класса protectedResources.todoListApi.endpoint. Этот элемент указывает URI веб-API. На основе URI веб-API перехватчик MSAL получает токен доступа с необходимыми областями доступа.
  3. Получает профиль из веб-API и задает profile переменную класса.
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;
      });
  }
}

В папке src/app/webapi обновите webapi.component.html следующим фрагментом HTML. Шаблон компонента отображает имя, которое возвращает веб-API. В нижней части страницы шаблон отображает адрес веб-API.

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

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

При необходимости обновите файл webapi.component.css с помощью следующего фрагмента CSS:

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

Запуск приложения Angular

Выполните следующую команду:

npm start

В окне консоли отображается номер порта, в котором размещено приложение.

Listening on port 4200...

Подсказка

В качестве альтернативы, чтобы выполнить команду npm start, используйте отладчик Visual Studio Code. Отладчик помогает ускорить процесс редактирования, компиляции и отладки.

Перейдите http://localhost:4200 в браузер, чтобы просмотреть приложение.

Дальнейшие шаги