Aktifkan autentikasi di aplikasi web Node Anda sendiri menggunakan Azure Active Directory B2C
Pada artikel ini, Anda akan mempelajari cara menambahkan autentikasi Azure Active Directory B2C (Azure AD B2C) di aplikasi web Node.js Anda sendiri. Anda akan mengizinkan pengguna untuk masuk, keluar, memperbarui profil, dan mengatur ulang kata sandi menggunakan alur pengguna Azure AD B2C. Artikel ini menggunakan Microsoft Authentication Library (MSAL) untuk Node untuk menyederhanakan penambahan autentikasi ke aplikasi web node Anda.
Tujuan artikel ini adalah untuk mengganti contoh aplikasi yang Anda gunakan dalam Mengonfigurasi autentikasi dalam contoh aplikasi web Node.js dengan menggunakan Azure AD B2C dengan aplikasi web Node.js Anda sendiri.
Artikel ini menggunakan Node.js dan Express untuk membuat aplikasi web Node.js dasar. Tampilan aplikasi menggunakan Handlebars.
Prasyarat
- Selesaikan langkah-langkah dalam Mengonfigurasi autentikasi dalam contoh aplikasi web Node.js dengan menggunakan Azure AD B2C. Anda akan membuat alur pengguna Azure AD B2C dan mendaftarkan aplikasi web di portal Azure.
Langkah 1: Buat proyek node
Buat folder untuk menghosting aplikasi node Anda, seperti active-directory-b2c-msal-node-sign-in-sign-out-webapp.
Di terminal Anda, ubah direktori ke folder aplikasi Node Anda, seperti
cd active-directory-b2c-msal-node-sign-in-sign-out-webapp, dan jalankannpm init -y. Perintah ini membuat filepackage.jsondefault untuk proyek Node.js Anda.Di terminal Anda, jalankan
npm install express. Perintah ini menginstal kerangka kerja Express.Buat lebih banyak folder dan file untuk mendapatkan struktur proyek berikut:
active-directory-b2c-msal-node-sign-in-sign-out-webapp/ ├── index.js └── package.json └── .env └── views/ └── layouts/ └── main.hbs └── signin.hbs
Folder views berisi file Handlebars untuk antarmuka pengguna aplikasi.
Langkah 2: Memasang dependensi aplikasi
Di terminal Anda, pasang paket dotenv, express-handlebars, express-session, dan @azure/msal-node dengan menjalankan perintah berikut:
npm install dotenv
npm install express-handlebars
npm install express-session
npm install @azure/msal-node
Langkah 3: Membangun komponen UI aplikasi
Dalam file main.hbs, tambahkan kode berikut:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>Tutorial | Authenticate users with MSAL for B2C</title>
<!-- adding Bootstrap 4 for UI components -->
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<link rel="SHORTCUT ICON" href="https://c.s-microsoft.com/favicon.ico?v2" type="image/x-icon">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<a class="navbar-brand" href="/">Microsoft Identity Platform</a>
{{#if showSignInButton}}
<div class="ml-auto">
<a type="button" id="SignIn" class="btn btn-secondary" href="/signin" aria-haspopup="true" aria-expanded="false">
Sign in
</a>
</div>
{{else}}
<div class="ml-auto">
<a type="button" id="EditProfile" class="btn btn-warning" href="/profile" aria-haspopup="true" aria-expanded="false">
Edit profile
</a>
<a type="button" id="PasswordReset" class="btn btn-warning" href="/password" aria-haspopup="true" aria-expanded="false">
Reset password
</a>
</div>
<p class="navbar-brand d-flex ms-auto">Hi {{givenName}}</p>
<a class="navbar-brand d-flex ms-auto" href="/signout">Sign out</a>
{{/if}}
</nav>
<br>
<h5 class="card-header text-center">MSAL Node Confidential Client application with Auth Code Flow</h5>
<br>
<div class="row" style="margin:auto" >
{{{body}}}
</div>
<br>
<br>
</body>
</html>
File main.hbs berada di folder layout. File tersebut harus berisi kode HTML yang diperlukan di seluruh aplikasi Anda. Setiap UI yang berubah dari satu tampilan ke tampilan lain, seperti di signin.hbs, ditempatkan di tempat penampung yang ditampilkan sebagai {{{body}}}.
File main.hbs mengimplementasikan antarmuka pengguna yang dibangun dengan kerangka kerja CSS Bootstrap 5. Anda akan melihat komponen antarmuka pengguna (tombol) Pengeditan kata sandi, Pengaturan ulang kata sandi, dan Keluar saat pengguna masuk. Anda akan melihat Masuk saat keluar. Perilaku ini dikontrol oleh showSignInButton variabel Boolean, yang dikirim oleh server aplikasi.
Dalam file signin.hbs, tambahkan kode berikut:
<div class="col-md-3" style="margin:auto">
<div class="card text-center">
<div class="card-body">
{{#if showSignInButton}}
<h5 class="card-title">Please sign-in to acquire an ID token</h5>
{{else}}
<h5 class="card-title">You have signed in</h5>
{{/if}}
</div>
<div class="card-body">
{{#if message}}
<h5 class="card-title text-danger">{{message}}</h5>
{{/if}}
</div>
</div>
</div>
Langkah 4: Konfigurasi server web dan klien MSAL
Dalam
.envfile, tambahkan kode berikut dan perbarui seperti yang dijelaskan dalam Konfigurasi sampel aplikasi web.#HTTP port SERVER_PORT=3000 #web apps client ID APP_CLIENT_ID=<You app client ID here> #session secret SESSION_SECRET=sessionSecretHere #web app client secret APP_CLIENT_SECRET=<Your app client secret here> #B2C sign up and sign in user flow/policy authority SIGN_UP_SIGN_IN_POLICY_AUTHORITY=https://<your-tenant-name>.b2clogin.com/<your-tenant-name>.onmicrosoft.com/<sign-in-sign-up-user-flow-name> #B2C password reset user flow/policy authority RESET_PASSWORD_POLICY_AUTHORITY=https://<your-tenant-name>.b2clogin.com/<your-tenant-name>.onmicrosoft.com/<reset-password-user-flow-name> #B2C edit profile user flow/policy authority EDIT_PROFILE_POLICY_AUTHORITY=https://<your-tenant-name>.b2clogin.com/<your-tenant-name>.onmicrosoft.com/<profile-edit-user-flow-name> #B2C authority domain AUTHORITY_DOMAIN=https://<your-tenant-name>.b2clogin.com #client redirect url APP_REDIRECT_URI=http://localhost:3000/redirect #Logout endpoint LOGOUT_ENDPOINT=https://<your-tenant-name>.b2clogin.com/<your-tenant-name>.onmicrosoft.com/<sign-in-sign-up-user-flow-name>/oauth2/v2.0/logout?post_logout_redirect_uri=http://localhost:3000Di file
index.jsAnda, tambahkan kode berikut untuk menggunakan dependensi aplikasi Anda:require('dotenv').config(); const express = require('express'); const session = require('express-session'); const {engine} = require('express-handlebars'); const msal = require('@azure/msal-node');Dalam
index.jsfile Anda, tambahkan kode berikut untuk mengonfigurasi pustaka autentikasi:/** * Confidential Client Application Configuration */ const confidentialClientConfig = { auth: { clientId: process.env.APP_CLIENT_ID, authority: process.env.SIGN_UP_SIGN_IN_POLICY_AUTHORITY, clientSecret: process.env.APP_CLIENT_SECRET, knownAuthorities: [process.env.AUTHORITY_DOMAIN], //This must be an array redirectUri: process.env.APP_REDIRECT_URI, validateAuthority: false }, system: { loggerOptions: { loggerCallback(loglevel, message, containsPii) { console.log(message); }, piiLoggingEnabled: false, logLevel: msal.LogLevel.Verbose, } } }; // Initialize MSAL Node const confidentialClientApplication = new msal.ConfidentialClientApplication(confidentialClientConfig);confidentialClientConfigkonfigurasi objek MSAL digunakan untuk terhubung ke titik akhir autentikasi penyewa AAD B2C Anda.Untuk menambahkan variabel global mode dalam
index.jsfile, tambahkan kode berikut:/** * The MSAL.js library allows you to pass your custom state as state parameter in the Request object * By default, MSAL.js passes a randomly generated unique state parameter value in the authentication requests. * The state parameter can also be used to encode information of the app's state before redirect. * You can pass the user's state in the app, such as the page or view they were on, as input to this parameter. * For more information, visit: https://docs.microsoft.com/azure/active-directory/develop/msal-js-pass-custom-state-authentication-request * In this scenario, the states also serve to show the action that was requested of B2C since only one redirect URL is possible. */ const APP_STATES = { LOGIN: 'login', LOGOUT: 'logout', PASSWORD_RESET: 'password_reset', EDIT_PROFILE : 'update_profile' } /** * Request Configuration * We manipulate these two request objects below * to acquire a token with the appropriate claims. */ const authCodeRequest = { redirectUri: confidentialClientConfig.auth.redirectUri, }; const tokenRequest = { redirectUri: confidentialClientConfig.auth.redirectUri, }; /** * Using express-session middleware. Be sure to familiarize yourself with available options * and set them as desired. Visit: https://www.npmjs.com/package/express-session */ const sessionConfig = { secret: process.env.SESSION_SECRET, resave: false, saveUninitialized: false, cookie: { secure: false, // set this to true on production } }APP_STATES: Digunakan untuk membedakan antara tanggapan yang diterima dari Azure Active Directory B2C dengan menandai permintaan. Hanya ada satu pengalihan URI untuk berapa pun jumlah permintaan yang dikirim ke Azure AD B2C.authCodeRequest: Objek konfigurasi yang digunakan untuk mengambil kode otorisasi.tokenRequest: Objek konfigurasi yang digunakan untuk mendapatkan token dengan kode otorisasi.sessionConfig: Objek konfigurasi untuk sesi Ekspres.
Untuk mengatur mesin templat tampilan dan konfigurasi sesi Ekspres, tambahkan kode berikut dalam file
index.js://Create an express instance const app = express(); //Set handlebars as your view engine app.engine('.hbs', engine({extname: '.hbs'})); app.set('view engine', '.hbs'); app.set("views", "./views"); //usse session configuration app.use(session(sessionConfig));
Langkah 5: Tambahkan rute ekspres
Sebelum Anda menambahkan rute aplikasi, tambahkan logika yang mengambil URL kode otorisasi, yang merupakan leg pertama alur pemberian kode otorisasi. Dalam file index.js, tambahkan kode berikut:
/**
* This method is used to generate an auth code request
* @param {string} authority: the authority to request the auth code from
* @param {array} scopes: scopes to request the auth code for
* @param {string} state: state of the application
* @param {Object} res: express middleware response object
*/
const getAuthCode = (authority, scopes, state, res) => {
// prepare the request
console.log("Fetching Authorization code")
authCodeRequest.authority = authority;
authCodeRequest.scopes = scopes;
authCodeRequest.state = state;
//Each time you fetch Authorization code, update the relevant authority in the tokenRequest configuration
tokenRequest.authority = authority;
// request an authorization code to exchange for a token
return confidentialClientApplication.getAuthCodeUrl(authCodeRequest)
.then((response) => {
console.log("\nAuthCodeURL: \n" + response);
//redirect to the auth code URL/send code to
res.redirect(response);
})
.catch((error) => {
res.status(500).send(error);
});
}
Objek authCodeRequest memiliki properti redirectUri, authority, scopes, dan state. Objek tersebut diteruskan ke metode getAuthCodeUrl sebagai parameter.
Dalam file index.js, tambahkan kode berikut:
app.get('/', (req, res) => {
res.render('signin', { showSignInButton: true });
});
app.get('/signin',(req, res)=>{
//Initiate a Auth Code Flow >> for sign in
//no scopes passed. openid, profile and offline_access will be used by default.
getAuthCode(process.env.SIGN_UP_SIGN_IN_POLICY_AUTHORITY, [], APP_STATES.LOGIN, res);
});
/**
* Change password end point
*/
app.get('/password',(req, res)=>{
getAuthCode(process.env.RESET_PASSWORD_POLICY_AUTHORITY, [], APP_STATES.PASSWORD_RESET, res);
});
/**
* Edit profile end point
*/
app.get('/profile',(req, res)=>{
getAuthCode(process.env.EDIT_PROFILE_POLICY_AUTHORITY, [], APP_STATES.EDIT_PROFILE, res);
});
/**
* Sign out end point
*/
app.get('/signout',async (req, res)=>{
logoutUri = process.env.LOGOUT_ENDPOINT;
req.session.destroy(() => {
//When session destruction succeeds, notify B2C service using the logout uri.
res.redirect(logoutUri);
});
});
app.get('/redirect',(req, res)=>{
//determine the reason why the request was sent by checking the state
if (req.query.state === APP_STATES.LOGIN) {
//prepare the request for authentication
tokenRequest.code = req.query.code;
confidentialClientApplication.acquireTokenByCode(tokenRequest).then((response)=>{
req.session.sessionParams = {user: response.account, idToken: response.idToken};
console.log("\nAuthToken: \n" + JSON.stringify(response));
res.render('signin',{showSignInButton: false, givenName: response.account.idTokenClaims.given_name});
}).catch((error)=>{
console.log("\nErrorAtLogin: \n" + error);
});
}else if (req.query.state === APP_STATES.PASSWORD_RESET) {
//If the query string has a error param
if (req.query.error) {
//and if the error_description contains AADB2C90091 error code
//Means user selected the Cancel button on the password reset experience
if (JSON.stringify(req.query.error_description).includes('AADB2C90091')) {
//Send the user home with some message
//But always check if your session still exists
res.render('signin', {showSignInButton: false, givenName: req.session.sessionParams.user.idTokenClaims.given_name, message: 'User has cancelled the operation'});
}
}else{
res.render('signin', {showSignInButton: false, givenName: req.session.sessionParams.user.idTokenClaims.given_name});
}
}else if (req.query.state === APP_STATES.EDIT_PROFILE){
tokenRequest.scopes = [];
tokenRequest.code = req.query.code;
//Request token with claims, including the name that was updated.
confidentialClientApplication.acquireTokenByCode(tokenRequest).then((response)=>{
req.session.sessionParams = {user: response.account, idToken: response.idToken};
console.log("\AuthToken: \n" + JSON.stringify(response));
res.render('signin',{showSignInButton: false, givenName: response.account.idTokenClaims.given_name});
}).catch((error)=>{
//Handle error
});
}else{
res.status(500).send('We do not recognize this response!');
}
});
Rute ekspres adalah:
/:- Digunakan untuk memasuki aplikasi web.
- Merender halaman
signin.
/signin:- Ini digunakan saat Anda masuk.
- Objek memanggil metode
getAuthCode()dan meneruskanauthorityuntuk kebijakan/alur pengguna Daftar dan masuk,APP_STATES.LOGIN, dan mengosongkan arrayscopes. - Jika perlu, itu menyebabkan tantangan pada Anda untuk memasukkan kredensial Anda. Jika Anda tidak memiliki akun, akun tersebut akan meminta Anda untuk mendaftar.
- Respons akhir yang dihasilkan dari titik akhir ini mencakup kode otorisasi dari Azure AD B2C yang diposting kembali ke
/redirecttitik akhir.
/password:- Ini digunakan saat Anda mengatur ulang kata sandi.
- Objek memanggil metode
getAuthCode()dan meneruskanauthorityuntuk kebijakan/alur pengguna Pengaturan ulang kata sandi,APP_STATES.PASSWORD_RESET, dan mengosongkan arrayscopes. - Ini memungkinkan Anda untuk mengubah kata sandi Anda dengan menggunakan pengalaman mengatur ulang kata sandi, atau mereka dapat membatalkan operasi.
- Respons akhir yang dihasilkan dari titik akhir ini mencakup kode otorisasi dari Azure AD B2C yang diposting kembali ke
/redirecttitik akhir. Jika Anda membatalkan operasi, kesalahan akan diposting kembali.
/profile:- Ini digunakan saat Anda memperbarui profil Anda.
- Objek memanggil metode
getAuthCode()dan melewatiauthorityuntuk kebijakan/alur pengguna Pengeditan profil,APP_STATES.EDIT_PROFILE, dan mengosongkan arrayscopes. - Ini memungkinkan Anda untuk memperbarui profil Anda, dan Anda menggunakan pengalaman mengedit profil.
- Respons akhir yang dihasilkan dari titik akhir ini mencakup kode otorisasi dari Azure AD B2C yang diposting kembali ke
/redirecttitik akhir.
/signout:- Ini digunakan saat Anda keluar.
- Aplikasi web menghapus sesi, dan melakukan panggilan HTTP ke titik akhir keluar Azure AD B2C.
/redirect:- Ini adalah rute yang ditetapkan sebagai URI Pengalihan untuk aplikasi web di portal Azure.
- Ini menggunakan
stateparameter kueri dalam permintaan dari Azure AD B2C untuk membedakan antara permintaan yang dibuat dari aplikasi web. Ini menangani semua proses pengalihan dari Azure AD B2C, kecuali untuk keluar. - Jika status aplikasi adalah
APP_STATES.LOGIN, kode otorisasi yang didapatkan akan digunakan untuk mengambil token melalui metodeacquireTokenByCode(). Token ini mencakupidTokendanidTokenClaims, yang digunakan untuk identifikasi pengguna. - Jika status aplikasi adalah
APP_STATES.PASSWORD_RESET, ia menangani kesalahan apa pun, sepertiuser cancelled the operation.AADB2C90091Kode kesalahan mengidentifikasi kesalahan ini. Jika tidak, ia memutuskan pengalaman pengguna berikutnya. - Jika status aplikasi adalah
APP_STATES.EDIT_PROFILE, kode otorisasi akan digunakan untuk mendapatkan token. Token berisiidTokenClaims, yang mencakup perubahan baru.
Langkah 6: Mulai server Node
Untuk memulai server Node, tambahkan kode berikut dalam file index.js:
app.listen(process.env.SERVER_PORT, () => {
console.log(`Msal Node Auth Code Sample app listening on port !` + process.env.SERVER_PORT);
});
Setelah Anda membuat semua perubahan yang diperlukan dalam index.js file, itu akan terlihat mirip dengan file berikut:
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
//<ms_docref_use_app_dependencies>
require('dotenv').config();
const express = require('express');
const session = require('express-session');
const {engine} = require('express-handlebars');
const msal = require('@azure/msal-node');
//</ms_docref_use_app_dependencies>
//<ms_docref_configure_msal>
/**
* Confidential Client Application Configuration
*/
const confidentialClientConfig = {
auth: {
clientId: process.env.APP_CLIENT_ID,
authority: process.env.SIGN_UP_SIGN_IN_POLICY_AUTHORITY,
clientSecret: process.env.APP_CLIENT_SECRET,
knownAuthorities: [process.env.AUTHORITY_DOMAIN], //This must be an array
redirectUri: process.env.APP_REDIRECT_URI,
validateAuthority: false
},
system: {
loggerOptions: {
loggerCallback(loglevel, message, containsPii) {
console.log(message);
},
piiLoggingEnabled: false,
logLevel: msal.LogLevel.Verbose,
}
}
};
// Initialize MSAL Node
const confidentialClientApplication = new msal.ConfidentialClientApplication(confidentialClientConfig);
//</ms_docref_configure_msal>
//<ms_docref_global_variable>
/**
* The MSAL.js library allows you to pass your custom state as state parameter in the Request object
* By default, MSAL.js passes a randomly generated unique state parameter value in the authentication requests.
* The state parameter can also be used to encode information of the app's state before redirect.
* You can pass the user's state in the app, such as the page or view they were on, as input to this parameter.
* For more information, visit: https://docs.microsoft.com/azure/active-directory/develop/msal-js-pass-custom-state-authentication-request
* In this scenario, the states also serve to show the action that was requested of B2C since only one redirect URL is possible.
*/
const APP_STATES = {
LOGIN: 'login',
LOGOUT: 'logout',
PASSWORD_RESET: 'password_reset',
EDIT_PROFILE : 'update_profile'
}
/**
* Request Configuration
* We manipulate these two request objects below
* to acquire a token with the appropriate claims.
*/
const authCodeRequest = {
redirectUri: confidentialClientConfig.auth.redirectUri,
};
const tokenRequest = {
redirectUri: confidentialClientConfig.auth.redirectUri,
};
/**
* Using express-session middleware. Be sure to familiarize yourself with available options
* and set them as desired. Visit: https://www.npmjs.com/package/express-session
*/
const sessionConfig = {
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
secure: false, // set this to true on production
}
}
//</ms_docref_global_variable>
//<ms_docref_view_tepmplate_engine>
//Create an express instance
const app = express();
//Set handlebars as your view engine
app.engine('.hbs', engine({extname: '.hbs'}));
app.set('view engine', '.hbs');
app.set("views", "./views");
//usse session configuration
app.use(session(sessionConfig));
//</ms_docref_view_tepmplate_engine>
//<ms_docref_authorization_code_url>
/**
* This method is used to generate an auth code request
* @param {string} authority: the authority to request the auth code from
* @param {array} scopes: scopes to request the auth code for
* @param {string} state: state of the application
* @param {Object} res: express middleware response object
*/
const getAuthCode = (authority, scopes, state, res) => {
// prepare the request
console.log("Fetching Authorization code")
authCodeRequest.authority = authority;
authCodeRequest.scopes = scopes;
authCodeRequest.state = state;
//Each time you fetch Authorization code, update the relevant authority in the tokenRequest configuration
tokenRequest.authority = authority;
// request an authorization code to exchange for a token
return confidentialClientApplication.getAuthCodeUrl(authCodeRequest)
.then((response) => {
console.log("\nAuthCodeURL: \n" + response);
//redirect to the auth code URL/send code to
res.redirect(response);
})
.catch((error) => {
res.status(500).send(error);
});
}
//</ms_docref_authorization_code_url>
//<ms_docref_app_endpoints>
app.get('/', (req, res) => {
res.render('signin', { showSignInButton: true });
});
app.get('/signin',(req, res)=>{
//Initiate a Auth Code Flow >> for sign in
//no scopes passed. openid, profile and offline_access will be used by default.
getAuthCode(process.env.SIGN_UP_SIGN_IN_POLICY_AUTHORITY, [], APP_STATES.LOGIN, res);
});
/**
* Change password end point
*/
app.get('/password',(req, res)=>{
getAuthCode(process.env.RESET_PASSWORD_POLICY_AUTHORITY, [], APP_STATES.PASSWORD_RESET, res);
});
/**
* Edit profile end point
*/
app.get('/profile',(req, res)=>{
getAuthCode(process.env.EDIT_PROFILE_POLICY_AUTHORITY, [], APP_STATES.EDIT_PROFILE, res);
});
/**
* Sign out end point
*/
app.get('/signout',async (req, res)=>{
logoutUri = process.env.LOGOUT_ENDPOINT;
req.session.destroy(() => {
//When session destruction succeeds, notify B2C service using the logout uri.
res.redirect(logoutUri);
});
});
app.get('/redirect',(req, res)=>{
//determine the reason why the request was sent by checking the state
if (req.query.state === APP_STATES.LOGIN) {
//prepare the request for authentication
tokenRequest.code = req.query.code;
confidentialClientApplication.acquireTokenByCode(tokenRequest).then((response)=>{
req.session.sessionParams = {user: response.account, idToken: response.idToken};
console.log("\nAuthToken: \n" + JSON.stringify(response));
res.render('signin',{showSignInButton: false, givenName: response.account.idTokenClaims.given_name});
}).catch((error)=>{
console.log("\nErrorAtLogin: \n" + error);
});
}else if (req.query.state === APP_STATES.PASSWORD_RESET) {
//If the query string has a error param
if (req.query.error) {
//and if the error_description contains AADB2C90091 error code
//Means user selected the Cancel button on the password reset experience
if (JSON.stringify(req.query.error_description).includes('AADB2C90091')) {
//Send the user home with some message
//But always check if your session still exists
res.render('signin', {showSignInButton: false, givenName: req.session.sessionParams.user.idTokenClaims.given_name, message: 'User has cancelled the operation'});
}
}else{
res.render('signin', {showSignInButton: false, givenName: req.session.sessionParams.user.idTokenClaims.given_name});
}
}else if (req.query.state === APP_STATES.EDIT_PROFILE){
tokenRequest.scopes = [];
tokenRequest.code = req.query.code;
//Request token with claims, including the name that was updated.
confidentialClientApplication.acquireTokenByCode(tokenRequest).then((response)=>{
req.session.sessionParams = {user: response.account, idToken: response.idToken};
console.log("\AuthToken: \n" + JSON.stringify(response));
res.render('signin',{showSignInButton: false, givenName: response.account.idTokenClaims.given_name});
}).catch((error)=>{
//Handle error
});
}else{
res.status(500).send('We do not recognize this response!');
}
});
//</ms_docref_app_endpoints>
//start app server to listen on set port
//<ms_docref_start_node_server>
app.listen(process.env.SERVER_PORT, () => {
console.log(`Msal Node Auth Code Sample app listening on port !` + process.env.SERVER_PORT);
});
//</ms_docref_start_node_server>
Langkah 7: Jalankan aplikasi web Anda
Ikuti langkah-langkah di Jalankan aplikasi web Anda untuk menguji aplikasi web Node.js Anda.