チュートリアル: ネイティブ認証 JavaScript SDK を使用して Angular シングルページ アプリにユーザーをサインアップする

適用対象: 次の内容が外部テナントに適用されることを示す白いチェック マーク記号が付いた緑の円。 外部テナント (詳細)

このチュートリアルでは、ネイティブ認証の JavaScript SDK を使用してユーザーをサインアップする Angular シングルページ アプリを構築する方法について説明します。

このチュートリアルでは、次の操作を行います。

  • Angular Next.js プロジェクトを作成します。
  • MSAL JS SDK を追加します。
  • アプリの UI コンポーネントを追加します。
  • ユーザーをサインアップするようにプロジェクトをセットアップします。

[前提条件]

React プロジェクトを作成して依存関係をインストールする

コンピューター内の任意の場所で、次のコマンドを実行して reactspa という名前の新しい Angular プロジェクトを作成し、プロジェクト フォルダーに移動して、パッケージをインストールします。

ng new angularspa
cd angularspa

コマンドを正常に実行すると、次の構造のアプリが作成されます。

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

JavaScript SDK をプロジェクトに追加する

アプリでネイティブ認証 JavaScript SDK を使用するには、ターミナルを使用して次のコマンドを使用してインストールします。

npm install @azure/msal-browser

ネイティブ認証機能は、 azure-msal-browser ライブラリの一部です。 ネイティブ認証機能を使用するには、 @azure/msal-browser/custom-authからインポートします。 例えば次が挙げられます。

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

クライアント構成の追加

このセクションでは、ネイティブ認証パブリック クライアント アプリケーションが SDK のインターフェイスと対話できるように構成を定義します。 そのためには、次の操作を実行します。

  1. src/app/config/auth-config.ts という名前のファイルを作成し、次のコードを追加します。

    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;
                    }
                },
            },
        },
    };
    

    コード内で、プレースホルダーを見つけてください:

    • Enter_the_Application_Id_Here をクリックし、先ほど登録したアプリのアプリケーション (クライアント) ID に置き換えます。

    • Enter_the_Tenant_Subdomain_Here 次に、Microsoft Entra 管理センターのテナント サブドメインに置き換えます。 たとえば、テナントのプライマリ ドメインが contoso.onmicrosoft.com の場合は、contoso を使用します。 テナント名がない場合は、テナントの詳細を読み取る方法を確認してください

  2. src/app/services/auth.service.ts という名前のファイルを作成し、次のコードを追加します。

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

サインアップ コンポーネントを作成する

  1. /app/components という名前のディレクトリを作成します。

  2. Angular CLI を使用して、次のコマンドを実行して、components フォルダー内のサインアップ ページの新しい コンポーネント を生成します。

    cd components
    ng generate component sign-up
    
  3. サインアップ/sign-up.component.ts ファイルを開き、その内容を sign-up.component の内容に置き換えます

  4. サインアップ/sign-up.component.htmlファイルを開き、html ファイルにコードを追加します。

    • sign-up.component.ts ファイル内の次のロジックは、サインアップ プロセスを開始した後にユーザーが次に実行する必要がある操作を決定します。 結果に応じて、ユーザーがサインアップ フローを続行できるように、パスワード フォームまたは確認コード フォームが sign-up.component.html に表示されます。

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

      SDK のインスタンス メソッド signUp() 、サインアップ フローを開始します。

    • サインアップが完了した直後にユーザーがサインイン フローを開始する場合は、次のスニペットを使用します。

      <div *ngIf="isSignedUp">
          <p>The user has been signed up, please click <a href="/sign-in">here</a> to sign in.</p>
      </div>
      
  5. src/app/app.component.scss ファイルを開き、次のスタイル ファイルを追加します。

サインアップ時にユーザー名 (エイリアス) を収集する

ユーザーがメールに加えてユーザー名 (エイリアス) でサインアップできるようにすることができます。 ユーザー名 (エイリアス) は、顧客 ID、アカウント番号、または選択した別の値などの代替サインイン識別子です。

サインアップ時には、プライマリ識別子としてユーザー名 (電子メール) が常に必要であり、ユーザー名 (エイリアス) によって置き換えられることはありません。 既定では、ユーザー名 (エイリアス) は省略可能ですが、管理者は必要に応じて構成できます。 アプリは常にユーザー名 (電子メール) を収集し、エイリアスを電子メールと共に属性として収集します。 サインイン時に、ユーザーはユーザー名 (電子メール) またはユーザー名 (エイリアス) を使用してサインインできます。 Username 属性をオプションまたは必須として構成する方法については、「ユーザー入力の種類とページ レイアウトを構成する」を参照してください。

サインアップ時にユーザー名 (エイリアス) を収集するには:

  1. サインアップ ユーザー フローで Username 組み込みユーザー属性が有効になっていることを確認します。 手順については、「 サインイン識別子ポリシーでユーザー名を有効にする」を参照してください。

  2. サインアップ コンポーネントにflatUsername フィールドを追加し、flatusernameに渡すUserAccountAttributessignUp()属性を含めます。

    flatUsername = "";
    
    const attributes: UserAccountAttributes = {
        givenName: this.firstName,
         //...
        flatusername: this.flatUsername,
    };
    
  3. 既存のフィールドと共に sign-up.component.html にエイリアス入力を追加します。

    <input type="text" [(ngModel)]="flatUsername" name="flatUsername" placeholder="Username (alias)" />
    
  4. ユーザー名 (エイリアス) に関連するエラーを処理します。

    • result.error?.isUserAlreadyExists() には、重複する電子メール または 重複するユーザー名 (エイリアス) が含まれます。 それに応じてメッセージを更新します。たとえば、 このメールまたはユーザー名を持つアカウントが既に存在します
    • 無効なユーザー名 (エイリアス) は、result.error?.isAttributesValidationFailed()ではなくresult.error?.isInvalidUsername()によって表示されます。 ユーザー名固有のメッセージを表示するには、このメソッドで分岐します。

サインアップ後に自動的にサインインする (省略可能)

新しいサインイン フローを開始せずに、正常にサインアップした後にユーザーを自動的にサインインさせることができます。 これを行うには、次のコード スニペットを使用します。 サインアップ/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;
        }
    }

ユーザーを自動署名する場合は、 サインアップ/ sign-up.component.htmlhtml ファイルで次のスニペットを使用します。

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

アプリのルーティングを更新する

  1. src/app/app.route.ts ファイルを開き、サインアップ コンポーネントのルートを追加します。

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

サインアップ フローをテストする

  1. CORS プロキシ サーバーを起動するには、ターミナルで次のコマンドを実行します。

    npm run cors
    
  2. アプリケーションを起動するには、ターミナルで次のコマンドを実行します。

    npm start
    
  3. Web ブラウザーを開き、http://localhost:4200/sign-upに移動します。 サインアップ フォームが表示されます。

  4. アカウントにサインアップするには、詳細を入力し、[ 続行 ] ボタンを選択し、プロンプトに従います。

次のステップ