Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Applies to: Workforce tenants
External tenants (learn more)
In this tutorial, you learn how to build an Angular single-page app that signs up users by using native authentication's JavaScript SDK.
In this tutorial, you:
- Create an Angular Next.js project.
- Add MSAL JS SDK to it.
- Add UI components of the app.
- Setup the project to sign up users.
Prerequisites
- Complete the steps in Quickstart: Sign in users in an Angular single-page app by using native authentication JavaScript SDK. This quickstart shows you run a sample Angular code sample.
- Complete the steps in Set up CORS proxy server to manage CORS headers for native authentication.
- Visual Studio Code or another code editor.
- Node.js.
- Angular CLI.
Create a React project and install dependencies
In a location of choice in your computer, run the following commands to create a new Angular project with the name reactspa, navigate into the project folder, then install packages:
ng new angularspa
cd angularspa
After you successfully run the commands, you should have an app with the following structure:
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
Add JavaScript SDK to your project
To use the native authentication JavaScript SDK in your app, use your terminal to install it by using the following command:
npm intall @azure/msal-browser
The native authentication capabilities are part of the azure-msal-browser
library. To use native authentication features, you import from @azure/msal-browser/custom-auth
. For example:
import CustomAuthPublicClientApplication from "@azure/msal-browser/custom-auth";
Add client configuration
In this section, you define a configuration for native authentication public client application to enable it to interact with the interface of the SDK. To do so,
Create a file called src/app/config/auth-config.ts, then add the following code:
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; } }, }, }, };
In the code, find the placeholder:
Enter_the_Application_Id_Here
then replace it with the Application (client) ID of the app you registered earlier.Enter_the_Tenant_Subdomain_Here
then replace it with the tenant subdomain in your Microsoft Entra admin center. For example, if your tenant primary domain iscontoso.onmicrosoft.com
, usecontoso
. If you don't have your tenant name, learn how to read your tenant details.
Create a file called src/app/services/auth.service.ts, then add the following code:
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; } }
Create a sign-up component
Create a directory called /app/components.
Use Angular CLI to generate a new component for the sign-up page inside the components folder by running the following command:
cd components ng generate component sign-up
Open sign-up/sign-up.component.ts file, then replace its contents with the contents in sign-up.component
Open sign-up/sign-up.component.html file and add the code in html file.
The following logic in the sign-up.component.ts file determines what the user needs to do next after starting the sign-up process. Depending on the result, it shows either the password form or the verification code form in sign-up.component.html so the user can continue with the sign-up flow:
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; }
The SDK's instance method,
signUp()
starts the sign-up flow.If you want the user to start sign-in flow immediately after sign-up is completed, use this snippet:
<div *ngIf="isSignedUp"> <p>The user has been signed up, please click <a href="/sign-in">here</a> to sign in.</p> </div>
Open the sign-up/sign-up.component.scss file, then add the following styles file.
Automatically sign-in after sign-up (optional)
You can automatically sign in your users after a successful sign-up without starting a fresh sign-in flow. To do so, use the following code snippet. See a complete example at 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;
}
}
When you autosign in a user, use the following snippet in your sign-up/sign-up.component.html html file.
<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>
Update app routing
Open the src/app/app.route.ts file, then add the route for the sign-up component:
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 { }
Test the sign-up flow
To start the CORS proxy server, run the following command in your terminal:
npm run cors
To start your application, run the following command in your terminal:
npm start
Open a web browser and navigate to
http://localhost:4200/sign-up
. A sign-up form appears.To sign up for an account, input your details, select the Continue button, then follow the prompts.