page_type | name | description | languages | products | urlFragment | extensions | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
sample |
Sign in users in a sample Node.js & Express web app by using Microsoft Entra External ID for customers |
This sample demonstrates a Node.js & Express web app authenticating users by using Microsoft Entra External ID for customers with Microsoft Authentication Library for Node (MSAL Node) |
|
|
ms-identity-ciam-javascript-tutorial-5-sign-in-express |
|
Sign in users in a sample Node.js (Express.js) web app by using Microsoft Entra External ID for customers
- Overview
- Usage
- Scenario
- Contents
- Prerequisites
- Setup the sample
- Explore the sample
- Troubleshooting
- About the code
- Contributing
- Learn More
This sample demonstrates how to sign users into a sample Node.js & Express web app by using Microsoft Entra External ID for customers. The samples utilizes the Microsoft Authentication Library for Node (MSAL Node) to simplify adding authentication to the Node.js web app.
Instruction | Description |
---|---|
Use case | This code sample applies to customer configuration uses case. If you're looking for a workforce configuration use case, use Tutorial: Enable a Node.js (Express) application to sign in users by using Microsoft Entra ID |
Scenario | Sign in users. You acquire an ID token by using authorization code flow with PKCE. |
Add sign in to your app | Use the instructions in Sign in users in a Node.js web app to learn how to add sign in to your Node web app. |
Product documentation | Explore Microsoft Entra ID for customers documentation |
File/folder | Description |
---|---|
App/app.js |
Application entry point. |
App/authConfig.js |
Contains authentication parameters such as your tenant sub-domain, Application (Client) ID, app client secret and redirect URI. |
App/auth/AuthProvider.js |
The main authentication logic resides here. |
/App/views/ |
This folder contains app views. This Node/Express sample app's views uses Handlebars. |
/App/routes/ |
This folder contains app's routes. |
- You must install Node.js in your computer to run this sample.
- We recommend Visual Studio Code for running and editing this sample.
- An external tenant. To create one, choose from the following methods:
- (Recommended) Use the Microsoft Entra External ID extension to set up an external tenant directly in Visual Studio Code.
- Create a new external tenant in the Microsoft Entra admin center.
- If you'd like to use Azure services, such as hosting your app in Azure App Service, VS Code Azure Tools extension is recommended for interacting with Azure through VS Code Interface.
You can register an app in your tenant automatically by using Microsoft Graph PowerShell or via the Microsoft Entra Admin center.
When you use Microsoft Graph PowerShell, you automatically register the applications and related objects app secrets, then modify your project config files, so you can run the app without any further action:
-
To register your app in the Microsoft Entra admin center use the steps in Register the web app.
-
To register and configure your app automatically,
Expand this section
⚠️ If you have never used Microsoft Graph PowerShell before, we recommend you go through the App Creation Scripts Guide once to ensure that you've prepared your environment correctly for this step.-
Ensure that you have PowerShell 7 or later installed.
-
Run the script to create your Microsoft Entra ID application and configure the code of the sample application accordingly.
-
For interactive process in PowerShell, run:
cd .\AppCreationScripts\ .\Configure.ps1 -TenantId "[Optional] - your tenant id" -AzureEnvironmentName "[Optional] - Azure environment, defaults to 'Global'"
Other ways of running the scripts are described in App Creation Scripts guide. The scripts also provides a guide to automated application registration, configuration and removal which can help in your CI/CD scenarios.
❗ NOTE: This sample can make use of client certificates. You can use AppCreationScripts to register an Microsoft Entra ID application with certificates. For more information see, Use client certificate for authentication in your Node.js web app instead of client secrets.
-
To create a client secret for the registered application, use the steps in Add app client secret
To grant delegated permissions, use the steps in Grant API permissions.
To create a user flow a customer can use to sign in or sign up for an application, use the steps in Create a user flow
To associate the web application with the user flow, use the steps in Associate the web application with the user flow.
To get the web app sample code, use the steps in Clone or download sample web application.
To install app dependencies, use the steps in Install project dependencies.
Once you download the sample app, you need to update it so that it uses the settings of the web app that you registered. To do so, use the steps in Configure the sample web app.
You can now test the sample Node.js web app. You need to start the Node.js server and access it through your browser at http://localhost:3000
. To do so, use the steps in Run and test sample web app.
ℹ️ If the sample didn't work for you as expected, reach out to us using the GitHub Issues page.
Were we successful in addressing your learning objective? Consider taking a moment to share your experience with us.
Expand for troubleshooting info
- Use Stack Overflow to get support from the community. Ask your questions on Stack Overflow first and browse existing issues to see if someone has asked your question before. Make sure that your questions or comments are tagged with [
azure-active-directory-b2c
node
ms-identity
adal
msal-js
msal
].
To provide feedback on or suggest features for Microsoft Entra ID or Microsoft Entra External ID, visit User Voice page.
In order to use MSAL Node, we instantiate the ConfidentialClientApplication:
-
Create the configuration object,
msalConfig
, as shown in the App/authConfig.js file:const msalConfig = { auth: { clientId: process.env.CLIENT_ID || 'Enter_the_Application_Id_Here', // 'Application (client) ID' of app registration in Microsoft Entra - this value is a GUID authority: process.env.AUTHORITY || `https://${TENANT_SUBDOMAIN}.ciamlogin.com/`, // Replace the placeholder with your tenant name clientSecret: process.env.CLIENT_SECRET || 'Enter_the_Client_Secret_Here', // Client secret generated from the app registration in Microsoft Entra admin center }, ... ... };
-
Use the
msalConfig
object to instantiate the confidential client application shown in the *App/auth/AuthProvider.js file (AuthProvider
class):... ... getMsalInstance(msalConfig) { return new msal.ConfidentialClientApplication(msalConfig); } .... ...
The first leg of auth code flow generates an authorization code request URL, then redirects to that URL to obtain the authorization code. This first leg is implemented in the redirectToAuthCodeUrl
method. Notice how we use MSALs getAuthCodeUrl method to generate authorization code URL, then redirect to the authorization code URL itself:
async redirectToAuthCodeUrl(req, res, next, authCodeUrlRequestParams, authCodeRequestParams, msalInstance) {
...
...
try {
const authCodeUrlResponse = await msalInstance.getAuthCodeUrl(req.session.authCodeUrlRequest);
res.redirect(authCodeUrlResponse);
} catch (error) {
next(error);
}
}
In the second leg of auth code flow uses, use the authorization code to request an ID token by using MSAL's acquireTokenByCode method. You can store the ID token and user account information in an express session.
async handleRedirect(req, res, next) {
const authCodeRequest = {
...req.session.authCodeRequest,
code: req.body.code, // authZ code
...
};
try {
const msalInstance = this.getMsalInstance(this.config.msalConfig);
msalInstance.getTokenCache().deserialize(req.session.tokenCache);
const tokenResponse = await msalInstance.acquireTokenByCode(authCodeRequest, req.body);
req.session.tokenCache = msalInstance.getTokenCache().serialize();
req.session.idToken = tokenResponse.idToken;
req.session.account = tokenResponse.account;
req.session.isAuthenticated = true;
...
...
} catch (error) {
next(error);
}
}
When you want to sign the user out of the application, it isn't enough to end the user's session. You must redirect the user to the logoutUri
. Otherwise, the user might be able to reauthenticate to your applications without reentering their credentials. If the name of your tenant is contoso, then the logoutUri looks similar to https://contoso.ciamlogin.com/contoso.onmicrosoft.com/oauth2/v2.0/logout?post_logout_redirect_uri=http://localhost:3000
.
async logout(req, res, next) {
/**
* Construct a logout URI and redirect the user to end the session with Microsoft Entra ID.
*/
const logoutUri = `${this.config.msalConfig.auth.authority}${TENANT_SUBDOMAIN}.onmicrosoft.com/oauth2/v2.0/logout?post_logout_redirect_uri=${this.config.postLogoutRedirectUri}`;
req.session.destroy(() => {
res.redirect(logoutUri);
});
}
There is one web app in this sample. To deploy it to Azure App Services, you'll need to:
*Create an Azure App Service *Publish the projects to the App Services, and *Update its client(s) to call the website instead of the local environment.
- In the VS Code activity bar, select the Azure logo to show the Azure App Service explorer.
- Select Sign in to Azure..., then follow the instructions. Once signed in, the explorer should show the name of your Azure subscription(s).
- On the App Service explorer section you see an upward-facing arrow icon. Select it publish your local files in the project folder to Azure App Services (use "Browse" option if needed, and locate the right folder).
- Choose a creation option based on the operating system to which you want to deploy. In this sample, we illustrate by using the Linux option.
- Select a Node.js version when prompted. We recommend a LTS version.
- Type a globally unique name for your web app and select Enter. The name must be unique across all of Azure services. After you respond to all the prompts, VS Code shows the Azure resources that are being created for your app in its notification popup.
- Select Yes when prompted to update your configuration. This action runs
npm install
on the target Linux server.
- Sign in to the Microsoft Entra admin center as at least an Application Developer.
- Browse to Identity >Applications > App registrations.
- From the app registration list, select the app that you want to update.
- Under Manage, select Authentication.
- Update your Redirect URIs to to match the site URL of your Azure deployment such as
https://ciam-msal-node-webapp.azurewebsites.net/auth/redirect
. - Select Configure to save your changes.
⚠️ If your app use in-memory storage, Azure App Services will spin down your web site if it is inactive. This action empties any records in the memory. In addition, if you increase the instance count of your website, Azure Service distributes the requests among the instances. Therefore, your app's records won't be the same on each instance.
If you'd like to contribute to this sample, see CONTRIBUTING.MD.
This project has adopted the Microsoft Open Source Code of Conduct. For more information, see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.