تمكين المصادقة في تطبيق Angular لديك باستخدام Azure Active Directory B2C

تتناول هذه المقالة كيفية إضافة مصادقة Azure Active Directory B2C (Azure AD B2C) إلى تطبيق Angular أحادي الصفحة (SPA). تعرف على كيفية دمج تطبيق Angular مع MSAL لمكتبة المصادقة في Angular.

استخدم هذه المقالة مع المقالة ذات الصلة بعنوان تكوين المصادقة في عينة لتطبيق Angular أحادي الصفحة. استبدل عينة تطبيق Angular بتطبيق Angular لديك. بعد إكمال الخطوات الواردة في هذه المقالة، سيقبل تطبيقك عمليات تسجيل الدخول عبر Azure AD B2C.

المتطلبات الأساسية

أكمل الخطوات الواردة في مقالة تكوين المصادقة في نموذج Angular تطبيق من صفحة واحدة.

إنشاء مشروع تطبيق Angular

يمكنك استخدام مشروع تطبيق Angular موجود أو إنشاء مشروع جديد. لإنشاء مشروع جديد، قم بتشغيل الأوامر التالية.

الأوامر:

  1. قم بتثبيت CLI Angular باستخدام مدير حزمة 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 ومكتبات MSAL Angular في تطبيقك، قم بتشغيل الأمر التالي في واجهة سطر الأوامر:

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

قم بتثبيت مكتبة مكون Angular Material (اختياري، لواجهة المستخدم):

npm install @angular/material @angular/cdk

إضافة مكونات المصادقة

تتكون عينة التعليمات البرمجية من المكونات التالية:

المكون النوع الوصف
auth-config.ts الثوابت يحتوي ملف التكوين هذا على معلومات حول موفر هوية Azure AD B2C وخدمة واجهة برمجة تطبيقات الويب. يستخدم تطبيق 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 في هذه المعاينة، يمكنك إضافة المكون الرئيسي لعرض الصفحة الرئيسية للوصول المجهول. ويوضح هذا المكون كيفية التحقق مما إذا كان المستخدم قد قام بتسجيل الدخول.
profile.component.* مكون Angular في هذه المعاينة، يمكنك إضافة مكون ملف التعريف لمعرفة كيفية قراءة مطالبات رمز المعرف.
webapi.component.* مكون Angular في هذه المعاينة، يمكنك إضافة مكون webapi لمعرفة كيفية استدعاء واجهة برمجة تطبيقات الويب.

لإضافة المكونات التالية إلى تطبيقك، قم بتشغيل أوامر 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 وواجهة برمجة تطبيقات الويب في ملف 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.
  2. قم باستيراد وحدة التكوين Azure AD B2C.
  3. استيراد HttpClientModule. يتم استخدام عميل HTTP لاستدعاء واجهات برمجة التطبيقات على الويب.
  4. قم باستيراد وحدة اعتراض HTTP Angular. تستخدم مكتبة MSAL وحدة الاعتراض لإدخال الرمز المميز للمالك في عنوان تخويل HTTP.
  5. أضف مواد Angular الأساسية.
  6. قم بإنشاء مثيل MSAL باستخدام كائن تطبيق العميل العام متعدد الحسابات. تتضمن تهيئة MSAL إدخال:
    1. كائن التكوين لدى auth-config.ts.
    2. كائن التكوين لطبقة حماية التوجيه.
    3. كائن التكوين لوحدة اعتراض MSAL. تكتسب فئة وحدة الاعتراض تلقائيًا الرموز المميزة للطلبات الصادرة التي تستخدم فئة Angular HttpClient لموارد محمية معروفة.
  7. قم بتكوين HTTP_INTERCEPTORS وMsalGuardAngular Provider.
  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.ts ثم قم بإجراء التغييرات التالية:

  1. أضف ارتباطًا إلى ملف التعريف ومكونات واجهة برمجة تطبيقات الويب.
  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>

استدعاء واجهة برمجة تطبيقات ويب

لاستدعاء واجهة برمجة تطبيقات ويب للتخويل المستندة إلى الرمز المميز، يحتاج التطبيق إلى رمز وصول صالح. يكتسب موفر MsalInterceptor تلقائيًا الرموز المميزة للطلبات الصادرة التي تستخدم فئة HttpClient في Angular للموارد المحمية المعروفة.

هام

يعمل أسلوب تهيئة MSAL (في الفئة app.module.ts) على تعيين الموارد المحمية، مثل واجهات برمجة تطبيقات الويب، مع نطاقات التطبيق المطلوبة باستخدام الكائن protectedResourceMap. إذا كانت التعليمات البرمجية لديك بحاجة إلى استدعاء واجهة برمجة تطبيقات ويب أخرى، فأضف عنوان واجهة برمجة تطبيقات الويب وأسلوب HTTP لواجهة برمجة تطبيقات الويب مع النطاقات المقابلة، إلى الكائن protectedResourceMap. لمزيدٍ من المعلومات، راجع مخطط الموارد المحمية.

عندما يستدعي عنصر HttpClient واجهة برمجة تطبيقات الويب، يتخذ موفر MsalInterceptor الخطوات التالية:

  1. يكتسب رمز وصول مع الأذونات (النطاقات) المطلوبة لنقطة نهاية واجهة برمجة تطبيقات الويب.

  2. يُدخل رمز الوصول كرمز مميز للحامل في عنوان التفويض لطلب HTTP باستخدام هذا التنسيق:

    Authorization: Bearer <access-token>
    

يوضح ملف web api.component كيفية استدعاء واجهة برمجة تطبيقات الويب. في المجلد src/app/webapi، قم بتحديث webapi.component.tsمن خلال قصاصة التعليمات البرمجية التالية.

التعليمة البرمجية:

  1. تستخدم الفئة httpClient في Angular لاستدعاء واجهة برمجة تطبيقات الويب.
  2. يمكنها قراءة العنصر protectedResources.todoListApi.endpoint للفئة auth-config. يحدد هذا العنصر عنوان URI لواجهة برمجة تطبيقات الويب. استنادًا إلى عنوان URI لواجهة برمجة تطبيقات الويب، تكتسب وحدة اعتراض MSAL رمز وصول من خلال النطاقات المقابلة.
  3. يحصل على ملف التعريف من واجهة برمجة تطبيقات الويب ويعين متغير الفئة 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 التالية. يعرض قالب المكون الاسم الذي تعرضه واجهة برمجة تطبيقات الويب. في الجزء السفلي من الصفحة، يعرض النموذج عنوان واجهة برمجة تطبيقات الويب.

<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. يساعد مصحح الأخطاء في تسريع وتيرة التحرير والترجمة والتصحيح.

انتقل إلى http://localhost:4200 في المستعرض لديك لعرض التطبيق.

الخطوات التالية