Esercitazione: Registrare gli utenti in un'applicazione Angular a pagina singola usando l'SDK JavaScript per l'autenticazione nativa

Si applica a: cerchio verde con un segno di spunta bianco che indica che il contenuto seguente si applica ai tenant esterni. Tenant esterni (altre informazioni)

Questa esercitazione illustra come creare un'app a pagina singola Angular che consente agli utenti di iscriversi usando JavaScript SDK per l'autenticazione nativa.

In questa esercitazione, farai:

  • Creare un progetto angular Next.js.
  • Aggiungi l'SDK MSAL JS.
  • Aggiungere componenti dell'interfaccia utente dell'app.
  • Configurare il progetto per consentire agli utenti di registrarsi.

Prerequisiti

Creare un progetto React e installare le dipendenze

In un percorso preferito nel computer eseguire i comandi seguenti per creare un nuovo progetto Angular con il nome reactspa, passare alla cartella del progetto e quindi installare i pacchetti:

ng new angularspa
cd angularspa

Dopo aver eseguito correttamente i comandi, è necessario avere un'app con la struttura seguente:

angularspa/
└──node_modules/
   └──...
└──public/
   └──...
└──src/
   └──app/
      └──app.component.html
      └──app.component.scss
      └──app.component.ts
      └──app.modules.ts
      └──app.config.ts
      └──app.routes.ts
   └──index.html
   └──main.ts
   └──style.scss
└──angular.json
└──package-lock.json
└──package.json
└──README.md
└──tsconfig.app.json
└──tsconfig.json
└──tsconfig.spec.json

Aggiungere JavaScript SDK al progetto

Per usare JavaScript SDK per l'autenticazione nativa nell'app, usare il terminale per installarlo usando il comando seguente:

npm install @azure/msal-browser

Le funzionalità di autenticazione nativa fanno parte della azure-msal-browser libreria. Per usare le funzionalità di autenticazione nativa, eseguire l'importazione da @azure/msal-browser/custom-auth. Per esempio:

  import CustomAuthPublicClientApplication from "@azure/msal-browser/custom-auth";

Aggiungi configurazione client

In questa sezione viene definita una configurazione per l'applicazione client pubblica di autenticazione nativa per consentire l'interazione con l'interfaccia dell'SDK. A tale scopo:

  1. Creare un file denominato src/app/config/auth-config.ts, quindi aggiungere il codice seguente:

    export const customAuthConfig: CustomAuthConfiguration = {
        customAuth: {
            challengeTypes: ["password", "oob", "redirect"],
            authApiProxyUrl: "http://localhost:3001/api",
        },
        auth: {
            clientId: "Enter_the_Application_Id_Here",
            authority: "https://Enter_the_Tenant_Subdomain_Here.ciamlogin.com",
            redirectUri: "/",
            postLogoutRedirectUri: "/",
            navigateToLoginRequestUrl: false,
        },
        cache: {
            cacheLocation: "sessionStorage",
        },
        system: {
            loggerOptions: {
                loggerCallback: (level: LogLevel, message: string, containsPii: boolean) => {
                    if (containsPii) {
                        return;
                    }
                    switch (level) {
                        case LogLevel.Error:
                            console.error(message);
                            return;
                        case LogLevel.Info:
                            console.info(message);
                            return;
                        case LogLevel.Verbose:
                            console.debug(message);
                            return;
                        case LogLevel.Warning:
                            console.warn(message);
                            return;
                    }
                },
            },
        },
    };
    

    Nel codice, trova il segnaposto:

    • Enter_the_Application_Id_Here sostituirlo quindi con l'ID applicazione (client) dell'app registrata in precedenza.

    • Enter_the_Tenant_Subdomain_Here sostituirlo quindi con il sottodominio tenant nell'interfaccia di amministrazione di Microsoft Entra. Ad esempio, se il dominio primario del tenant è contoso.onmicrosoft.com, usare contoso. Se non hai il nome del tuo locatario, scopri come leggere i dettagli del locatario.

  2. Creare un file denominato src/app/services/auth.service.ts, quindi aggiungere il codice seguente:

    import { Injectable } from '@angular/core';
    import { CustomAuthPublicClientApplication, ICustomAuthPublicClientApplication } from '@azure/msal-browser/custom-auth';
    import { customAuthConfig } from '../config/auth-config';
    
    @Injectable({ providedIn: 'root' })
    export class AuthService {
      private authClientPromise: Promise<ICustomAuthPublicClientApplication>;
      private authClient: ICustomAuthPublicClientApplication | null = null;
    
      constructor() {
        this.authClientPromise = this.init();
      }
    
      private async init(): Promise<ICustomAuthPublicClientApplication> {
        this.authClient = await CustomAuthPublicClientApplication.create(customAuthConfig);
        return this.authClient;
      }
    
      getClient(): Promise<ICustomAuthPublicClientApplication> {
        return this.authClientPromise;
      }
    }
    

Crea un componente di registrazione

  1. Creare una directory denominata /app/components.

  2. Usare l'interfaccia della riga di comando di Angular per generare un nuovo componente per la pagina di iscrizione all'interno della cartella dei componenti eseguendo il comando seguente:

    cd components
    ng generate component sign-up
    
  3. Apri sign-up/sign-up.component.ts, quindi sostituisci il suo contenuto con il contenuto di sign-up.component

  4. Aprire il file di iscrizione/sign-up.component.html e aggiungere il codice nel file HTML.

    • La logica seguente nel file sign-up.component.ts determina le operazioni che l'utente deve eseguire dopo l'avvio del processo di iscrizione. A seconda del risultato, viene visualizzato il modulo della password o il modulo del codice di verifica in sign-up.component.html in modo che l'utente possa continuare con il flusso di iscrizione:

         const attributes: UserAccountAttributes = {
                     givenName: this.firstName,
                     surname: this.lastName,
                     jobTitle: this.jobTitle,
                     city: this.city,
                     country: this.country,
                 };
         const result = await client.signUp({
                     username: this.email,
                     attributes,
                 });
      
         if (result.isPasswordRequired()) {
             this.showPassword = true;
             this.showCode = false;
         } else if (result.isCodeRequired()) {
             this.showPassword = false;
             this.showCode = true;
         }
      

      Il metodo signUp() di istanza dell'SDK avvia il flusso di iscrizione.

    • Se si vuole che l'utente avvii il flusso di accesso immediatamente dopo il completamento dell'iscrizione, usare questo frammento di codice:

      <div *ngIf="isSignedUp">
          <p>The user has been signed up, please click <a href="/sign-in">here</a> to sign in.</p>
      </div>
      
  5. Aprire il file src/app/app.component.scss , quindi aggiungere il file di stili seguente.

Richiedere un nome utente (alias) durante l'iscrizione

È possibile consentire agli utenti di iscriversi con un nome utente (alias) oltre alla posta elettronica. Il nome utente (alias) è un identificatore di accesso alternativo, ad esempio un ID cliente, un numero di account o un altro valore scelto.

Durante l'iscrizione, il nome utente (indirizzo di posta elettronica) è sempre necessario come identificatore primario e il nome utente (alias) non lo sostituisce. Per impostazione predefinita, il nome utente (alias) è facoltativo, anche se un amministratore può configurarlo in base alle esigenze. L'app raccoglie sempre il nome utente (indirizzo di posta elettronica) e raccoglie l'alias come attributo insieme al messaggio di posta elettronica. All'accesso, l'utente può quindi accedere con il nome utente (indirizzo di posta elettronica) o il nome utente (alias). Per informazioni su come l'attributo Username è configurato come facoltativo o obbligatorio, vedere Configurare i tipi di input utente e il layout di pagina.

Per raccogliere un nome utente (alias) durante l'iscrizione:

  1. Assicurarsi che l'attributo utente predefinito Username sia abilitato nel flusso utente di iscrizione. Per la procedura, vedere Abilitare il nome utente nei criteri di identificatore di accesso.

  2. Aggiungere un campo flatUsername al componente di registrazione, quindi includere l'attributo flatusername nell'UserAccountAttributes che passi a signUp():

    flatUsername = "";
    
    const attributes: UserAccountAttributes = {
        givenName: this.firstName,
         //...
        flatusername: this.flatUsername,
    };
    
  3. Aggiungere un input alias a sign-up.component.html insieme ai campi esistenti:

    <input type="text" [(ngModel)]="flatUsername" name="flatUsername" placeholder="Username (alias)" />
    
  4. Gestire gli errori correlati al nome utente (alias):

    • result.error?.isUserAlreadyExists() copre un messaggio di posta elettronica duplicato o un nome utente duplicato (alias). Aggiornare il messaggio di conseguenza, ad esempio Un account con questo indirizzo di posta elettronica o nome utente esiste già.
    • Un nome utente (alias) non valido viene visualizzato tramite result.error?.isAttributesValidationFailed() anziché result.error?.isInvalidUsername(). Aggiungere una diramazione in questo metodo per visualizzare un messaggio specifico per il nome utente.

Accesso automatico dopo l'iscrizione (facoltativo)

È possibile accedere automaticamente agli utenti dopo l'iscrizione senza avviare un nuovo flusso di accesso. A tale scopo, usare il frammento di codice seguente. Vedi un esempio completo in sign-up/sign-up.component.ts:

    if (this.signUpState instanceof SignUpCompletedState) {
        const result = await this.signUpState.signIn();
    
        if (result.isFailed()) {
            this.error = result.error?.errorData?.errorDescription || "An error occurred during auto sign-in";
        }
    
        if (result.isCompleted()) {
            this.userData = result.data;
            this.signUpState = result.state;
            this.isSignedUp = true;
            this.showCode = false;
            this.showPassword = false;
        }
    }

Quando si effettua l'accesso automatico di un utente, usare il seguente frammento di codice nel file HTML sign-up/sign-up.component.html.

    <div *ngIf="userData && !isSignedIn">
        <p>Signed up complete, and signed in as {{ userData?.getAccount()?.username }}</p>
    </div>
    <div *ngIf="isSignedUp && !userData">
        <p>Sign up completed! Signing you in automatically...</p>
    </div>

Aggiornare il routing delle app

  1. Aprire il file src/app/app.route.ts , quindi aggiungere la route per il componente di iscrizione:

    import { NgModule } from '@angular/core';
    import { RouterModule, Routes } from '@angular/router';
    import { SignUpComponent } from './components/sign-up/sign-up.component';
    import { AuthService } from './services/auth.service';
    import { AppComponent } from './app.component';
    
    export const routes: Routes = [
        { path: 'sign-up', component: SignUpComponent },
    ];
    
    @NgModule({
        imports: [
            RouterModule.forRoot(routes),
            SignUpComponent,
        ],
        providers: [AuthService],
        bootstrap: [AppComponent]
    })
    export class AppRoutingModule { }
    

Testare il flusso di iscrizione

  1. Per avviare il server proxy CORS, eseguire il comando seguente nel terminale:

    npm run cors
    
  2. Per avviare l'applicazione, eseguire il comando seguente nel terminale:

    npm start
    
  3. Aprire un Web browser e passare a http://localhost:4200/sign-up. Viene visualizzato un modulo di iscrizione.

  4. Per iscriversi a un account, immettere i dettagli, selezionare il pulsante Continua e quindi seguire le istruzioni.

Passo successivo