問題描述
在上一篇博文 “【Azure 應用服務】NodeJS Express + MSAL 應用實現AAD整合登入並部署在App Service Linux環境中的實現步驟”中,實現了登入,並獲取登入使用者在AAD中的個人資訊,但是沒有一個顯示的方法輸出所獲取到的Access Token,則通過新建Express專案,載入MSAL的程式碼實現此目的。
實現步驟
第一步:建立 NodeJS Express專案,並新增@azure/msal-node 專案包
前提條件:安裝 Node.js 和 VS Code
使用npm安全express專案生成器
npm install -g express-generator
在當前目錄在生成 express專案預設檔案
express --view=hbs
開始生成專案檔案
npm install
安裝MSAL package
npm install --save @azure/msal-node
專案生成後的完整路徑
myExpressWebApp/ ├── bin/ | └── wwww ├── public/ | ├── images/ | ├── javascript/ | └── stylesheets/ | └── style.css ├── routes/ | ├── index.js | └── users.js ├── views/ | ├── error.hbs | ├── index.hbs | └── layout.hbs ├── app.js └── package.json
第二步:在 app.js 中新增 MSAL object,新增 '/auth' 介面登入AAD並獲取Access Token
引入 msal 物件
const msal = require('@azure/msal-node');
配置AAD Authentication 引數 clientId, authority 和 clientSecret (與上一篇博文中第一步相同, 也需要新增 http://localhost:3000/redirect 在 AAD註冊應用的Redirect URIs中)。
// Authentication parameters const config = { auth: { clientId: " Enter_the_Application_Id_Here", authority: "https://login.partner.microsoftonline.cn/<#Enter_the_Tenant_Info_Here>", clientSecret: "xxxxxx.xxxxxxxxxxxxxxxxx" #Enter_the_Client_Secret_Here }, system: { loggerOptions: { loggerCallback(loglevel, message, containsPii) { console.log(message); }, piiLoggingEnabled: false, logLevel: msal.LogLevel.Verbose, } } }; const REDIRECT_URI = "http://localhost:3000/redirect";
然後根據上一步的config引數初始化 msal confidential client applicaiton物件
// Initialize MSAL Node object using authentication parameters const cca = new msal.ConfidentialClientApplication(config);
app.get('/auth', (req, res) => { // Construct a request object for auth code const authCodeUrlParameters = { scopes: ["user.read"], redirectUri: REDIRECT_URI, }; // Request auth code, then redirect cca.getAuthCodeUrl(authCodeUrlParameters) .then((response) => { res.redirect(response); }).catch((error) => res.send(error)); }); app.get('/redirect', (req, res) => { // Use the auth code in redirect request to construct // a token request object const tokenRequest = { code: req.query.code, scopes: ["user.read"], redirectUri: REDIRECT_URI, }; // Exchange the auth code for tokens cca.acquireTokenByCode(tokenRequest) .then((response) => { res.send(response); }).catch((error) => res.status(500).send(error)); });
完整 app.js 程式碼為:
var createError = require('http-errors'); var express = require('express'); var path = require('path'); var cookieParser = require('cookie-parser'); var logger = require('morgan'); var indexRouter = require('./routes/index'); var usersRouter = require('./routes/users'); const msal = require('@azure/msal-node'); // Authentication parameters const config = { auth: { clientId: " Enter_the_Application_Id_Here", authority: "https://login.partner.microsoftonline.cn/<#Enter_the_Tenant_Info_Here>", clientSecret: "xxxxxx.xxxxxxxxxxxxxxxxx" #Enter_the_Client_Secret_Here }, system: { loggerOptions: { loggerCallback(loglevel, message, containsPii) { console.log(message); }, piiLoggingEnabled: false, logLevel: msal.LogLevel.Verbose, } } }; const REDIRECT_URI = "http://localhost:3000/redirect"; // Initialize MSAL Node object using authentication parameters const cca = new msal.ConfidentialClientApplication(config); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'hbs'); app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', indexRouter); app.use('/users', usersRouter); app.get('/auth', (req, res) => { // Construct a request object for auth code const authCodeUrlParameters = { scopes: ["user.read"], redirectUri: REDIRECT_URI, }; // Request auth code, then redirect cca.getAuthCodeUrl(authCodeUrlParameters) .then((response) => { res.redirect(response); }).catch((error) => res.send(error)); }); app.get('/redirect', (req, res) => { // Use the auth code in redirect request to construct // a token request object const tokenRequest = { code: req.query.code, scopes: ["user.read"], redirectUri: REDIRECT_URI, }; // Exchange the auth code for tokens cca.acquireTokenByCode(tokenRequest) .then((response) => { res.send(response); }).catch((error) => res.status(500).send(error)); }); // catch 404 and forward to error handler app.use(function(req, res, next) { next(createError(404)); }); // error handler app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; // render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app;
執行效果動畫展示:
參考資料
NodeJS Express + MSAL 應用實現AAD整合登入並部署在App Service Linux環境中的實現步驟:https://www.cnblogs.com/lulight/p/16353145.html
Tutorial: Sign in users and acquire a token for Microsoft Graph in a Node.js & Express web app: https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-nodejs-webapp-msal
Example: Acquiring tokens with ADAL Node vs. MSAL Node:https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-node-migration#example-acquiring-tokens-with-adal-node-vs-msal-node