Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Než začnete tady, ujistěte se, že rozumíte tomu, jak inicializovat objekt aplikace.
@azure/msal-angular používá systém událostí vystavený službou @azure/msal-browser, která generuje události související s ověřováním a knihovnou MSAL, a lze ji použít k aktualizaci uživatelského rozhraní, zobrazení chybových zpráv atd.
Zpracování událostí ve vaší aplikaci
Události v @azure/msal-angular spravuje MsalBroadcastService a jsou k dispozici po přihlášení k odběru observable msalSubject$ v objektu MsalBroadcastService.
Zde je příklad, jak můžete ve své aplikaci zpracovávat emitované události:
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();
}
}
Upozorňujeme, že možná budete muset přetypovat result.payload jako konkrétní typ, aby se zabránilo chybám kompilace. Typ datové části bude záviset na události a najdete ho v naší dokumentaci zde.
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);
});
}
Úplný příklad použití událostí najdete tady v naší ukázce.
Tabulka událostí
Další informace o objektu EventMessage, včetně úplné tabulky událostí, které @azure/msal-browser aktuálně emituje (včetně popisů a souvisejících payloadů), naleznete v dokumentaci zde.
Zpracování chyb pomocí událostí
Protože je EventError v EventMessage definován jako AuthError | Error | null, měla by se před přístupem k jejím konkrétním vlastnostem ověřit, že chyba má správný typ.
Níže je uveden příklad, jak lze chybu přetypovat na AuthError, aby se předešlo chybám TypeScriptu:
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();
}
}
Příklad zpracování chyb najdete také v naší ukázce MSAL Angular B2C.
Synchronizace přihlášeného stavu napříč kartami a okny
Pokud chcete aktualizovat uživatelské rozhraní, když se uživatel v jiné kartě nebo okně přihlásí k aplikaci nebo se z ní odhlásí, můžete se přihlásit k událostem ACCOUNT_ADDED a ACCOUNT_REMOVED. Datovou zátěž bude tvořit objekt AccountInfo, který byl přidán nebo odebrán.
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();
}
}
Úplný příklad najdete také v našich ukázkách.
Pozorovatelná hodnota inProgress$
Observable inProgress$ také zpracovává MsalBroadcastService a je vhodné se k němu přihlásit k odběru, když aplikace potřebuje znát stav interakcí, zejména kvůli ověření, že interakce byly dokončeny. Doporučujeme zkontrolovat stav interakcí InteractionStatus.None před funkcemi zahrnujícími uživatelské účty.
Všimněte si, že poslední / nejnovější InteractionStatus bude také k dispozici při přihlášení k inProgress$ observable.
Podívejte se na následující příklad pro jeho použití. Úplný příklad najdete také v našich ukázkách. Úplný seznam stavů interakce najdete tady.
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();
}
}
Volitelné MsalBroadcastService konfigurace
Volitelně MsalBroadcastService můžete nakonfigurovat, aby se při přihlášení k odběru přehrály minulé události. Ve výchozím nastavení jsou k dispozici události, které jsou vyvolány poté, co se přihlásíte k odběru MsalBroadcastService. Můžou existovat případy, kdy jsou potřeba události před předplatným. Pokud zadáte konfiguraci pro MsalBroadcastService a nastavíte parametr eventsToReplay na číslo, bude při přihlášení k odběru k dispozici tento počet minulých událostí.
Další informace o přehrání událostí najdete v dokumentaci RxJS na webu ReplaySubjects zde.
V MsalBroadcastService souboru app.module.ts je možné ho nakonfigurovat následujícím způsobem:
// 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 {}