Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Innan du börjar här bör du se till att du förstår hur du initierar programobjektet.
@azure/msal-angular använder händelsesystemet som exponeras av @azure/msal-browser, som genererar händelser relaterade till autentisering och MSAL, och kan användas för att uppdatera användargränssnittet, visa felmeddelanden och så vidare.
Hantera händelser i din app
Händelser i @azure/msal-angular hanteras av MsalBroadcastService och kan användas genom att prenumerera på det observerbara objektet msalSubject$ på MsalBroadcastService.
Här är ett exempel på hur du kan använda de avgivna händelserna i ditt program:
import { MsalBroadcastService } from '@azure/msal-angular';
import { EventMessage, EventType } from '@azure/msal-browser';
export class AppComponent implements OnInit, OnDestroy {
private readonly _destroying$ = new Subject<void>();
constructor(
//...
private msalBroadcastService: MsalBroadcastService
) {}
ngOnInit(): void {
this.msalBroadcastService.msalSubject$
.pipe(
// Optional filtering of events.
filter((msg: EventMessage) => msg.eventType === EventType.LOGIN_SUCCESS),
takeUntil(this._destroying$)
)
.subscribe((result: EventMessage) => {
// Do something with the result
});
}
ngOnDestroy(): void {
this._destroying$.next(null);
this._destroying$.complete();
}
}
Observera att du kan behöva typkonvertera result.payload till en specifik typ för att undvika kompileringsfel. Typ av nyttolast beror på händelsen och kan hittas i vår dokumentation här.
ngOnInit(): void {
this.msalBroadcastService.msalSubject$
.pipe(
filter((msg: EventMessage) => msg.eventType === EventType.LOGIN_SUCCESS),
)
.subscribe((result: EventMessage) => {
// Casting payload as AuthenticationResult to access account
const payload = result.payload as AuthenticationResult;
this.authService.instance.setActiveAccount(payload.account);
});
}
Det fullständiga exemplet på hur du använder händelser finns i vårt exempel här.
Tabell över händelser
Mer information om EventMessage objektet, inklusive den fullständiga tabellen med händelser som för närvarande genereras av @azure/msal-browser (inklusive beskrivningar och relaterade nyttolaster) finns i dokumentationen här.
Felhantering med händelser
Eftersom EventError i EventMessage definieras som AuthError | Error | null bör ett fel kontrolleras vara av rätt typ innan man använder specifika egenskaper på det.
Se exemplet nedan på hur ett fel kan typomvandlas till AuthError för att undvika TypeScript-fel:
import { MsalBroadcastService } from '@azure/msal-angular';
import { EventMessage, EventType } from '@azure/msal-browser';
export class AppComponent implements OnInit, OnDestroy {
private readonly _destroying$ = new Subject<void>();
constructor(
//...
private msalBroadcastService: MsalBroadcastService
) {}
ngOnInit(): void {
this.msalBroadcastService.msalSubject$
.pipe(
// Optional filtering of events
filter((msg: EventMessage) => msg.eventType === EventType.LOGIN_FAILURE),
takeUntil(this._destroying$)
)
.subscribe((result: EventMessage) => {
if (result.error instanceof AuthError) {
// Do something with the error
}
});
}
ngOnDestroy(): void {
this._destroying$.next(null);
this._destroying$.complete();
}
}
Ett exempel på felhantering finns också i vårt MSAL Angular B2C-exempel.
Synkronisering av inloggningsstatus mellan flikar och fönster
Om du vill uppdatera användargränssnittet när en användare loggar in eller ut i din app på en annan flik eller i ett annat fönster, kan du prenumerera på händelserna ACCOUNT_ADDED och ACCOUNT_REMOVED. Nyttolasten är det AccountInfo objekt som har lagts till eller tagits bort.
import { MsalService, MsalBroadcastService } from '@azure/msal-angular';
import { EventMessage, EventType } from '@azure/msal-browser';
export class AppComponent implements OnInit, OnDestroy {
private readonly _destroying$ = new Subject<void>();
constructor(
//...
private authService: MsalService,
private msalBroadcastService: MsalBroadcastService
) {}
ngOnInit(): void {
this.authService.instance.enableAccountStorageEvents(); // Register the storage listener that will be emitting the events
this.msalBroadcastService.msalSubject$
.pipe(
// Optional filtering of events
filter((msg: EventMessage) => msg.eventType === EventType.ACCOUNT_ADDED || msg.eventType === EventType.ACCOUNT_REMOVED),
takeUntil(this._destroying$)
)
.subscribe((result: EventMessage) => {
if (this.authService.msalInstance.getAllAccounts().length === 0) {
// Account logged out in a different tab, redirect to homepage
window.location.pathname = "/";
} else {
// Update UI to show user is signed in. result.payload contains the account that was logged in
}
});
}
ngOnDestroy(): void {
this._destroying$.next(null);
this._destroying$.complete();
}
}
Ett fullständigt exempel finns också i våra exempel.
The inProgress$ Observable
Det inProgress$ observerbara hanteras också av MsalBroadcastService, och bör prenumereras på när programmet behöver känna till statusen för interaktioner, särskilt för att kontrollera att interaktioner har slutförts. Vi rekommenderar att du kontrollerar att statusen för interaktioner är InteractionStatus.None före funktioner som involverar användarkonton.
Observera att den sista/senaste InteractionStatus också kommer att vara tillgänglig när du prenumererar på inProgress$-observable.
Se exemplet nedan för dess användning. Ett fullständigt exempel finns också i våra exempel. En fullständig lista över interaktionsstatusar finns här.
import { Component, OnInit, Inject, OnDestroy } from '@angular/core';
import { MsalBroadcastService} from '@azure/msal-angular';
import { InteractionStatus } 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']
})
export class AppComponent implements OnInit, OnDestroy {
private readonly _destroying$ = new Subject<void>();
constructor(
private msalBroadcastService: MsalBroadcastService
) {}
ngOnInit(): void {
this.msalBroadcastService.inProgress$
.pipe(
// Filtering for all interactions to be completed
filter((status: InteractionStatus) => status === InteractionStatus.None),
takeUntil(this._destroying$)
)
.subscribe(() => {
// Do something related to user accounts or UI here
})
}
ngOnDestroy(): void {
this._destroying$.next(null);
this._destroying$.complete();
}
}
Valfri MsalBroadcastService konfiguration
MsalBroadcastService kan valfritt konfigureras för att spela upp tidigare händelser vid prenumeration. Som standard är händelser som utlöses efter att du har börjat prenumerera på MsalBroadcastService tillgängliga. Det kan finnas fall där man behöver händelser från tiden före en prenumeration. Genom att ange en konfiguration för MsalBroadcastService och ställa in parametern eventsToReplay på ett tal blir det antalet tidigare händelser tillgängliga vid prenumerationen.
Mer information om hur du spelar upp händelser finns i RxJS-dokumenten på ReplaySubjects här.
MsalBroadcastService Kan konfigureras i app.module.ts-filen på följande sätt:
// app.module.ts
import { NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AppComponent } from './app.component';
import { MsalModule, MsalService, MsalGuard, MsalInterceptor, MsalBroadcastService, MsalRedirectComponent, MSAL_BROADCAST_CONFIG } from "@azure/msal-angular"; // Import MsalBroadcastService and MSAL_BROADCAST_CONFIG here
import { PublicClientApplication, InteractionType, BrowserCacheLocation } from "@azure/msal-browser";
@NgModule({
imports: [
MsalModule.forRoot( new PublicClientApplication({ // MSAL Configuration
auth: {
clientId: "clientid",
authority: "https://login.microsoftonline.com/common/",
redirectUri: "http://localhost:4200/",
postLogoutRedirectUri: "http://localhost:4200/",
navigateToLoginRequestUrl: true
},
cache: {
cacheLocation : BrowserCacheLocation.LocalStorage,
},
system: {
loggerOptions: {
loggerCallback: () => {},
piiLoggingEnabled: false
}
}
}), {
interactionType: InteractionType.Popup, // MSAL Guard Configuration
authRequest: {
scopes: ['user.read']
},
loginFailedRoute: "/login-failed"
}, {
interactionType: InteractionType.Redirect, // MSAL Interceptor Configuration
protectedResourceMap
})
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: MsalInterceptor,
multi: true
},
{
provide: MSAL_BROADCAST_CONFIG, // Add configuration to providers here
useValue: {
eventsToReplay: 2 // Set how many events you want to replay when subscribing
}
},
MsalGuard,
MsalBroadcastService // Ensure the MsalBroadcastService is provided
],
bootstrap: [AppComponent, MsalRedirectComponent]
})
export class AppModule {}