nodejs接入微软登陆(MSAL)

参考链接

做了两个例子:express 和 eggjs,详情如下:

先决条件

  • Nodejs
  • VS Code 或其他代码编辑器

注册应用程序

首先,请完成向 Microsoft 标识平台注册应用程序中的步骤来注册你的应用。

对于应用注册,请使用以下设置:

  • 名称:ExpressWebApp(建议)
  • 支持的帐户类型:任何组织目录中的帐户(任何 Azure AD 目录 - 多租户)和个人 Microsoft 帐户(例如 Skype、Xbox)
  • 平台类型:Web
  • 重定向 URI:http://localhost:3000/redirect
  • 客户端机密:*********(记录此值以便在后面的步骤中使用 - 它只显示一次)

express环境

const msal = require('@azure/msal-node');
const express = require("express");

const config = {
  auth: {
    clientId: "******",
    authority: "********",
    clientSecret: "********"
  },
  system: {
      loggerOptions: {
          loggerCallback(loglevel, message, containsPii) {
              console.log(message);
          },
          piiLoggingEnabled: false,
          logLevel: msal.LogLevel.Verbose,
      }
  }
};
const cca = new msal.ConfidentialClientApplication(config);

const SERVER_PORT = process.env.PORT || 3001;

const app = express();

// redirectUri:接口2 redirect地址 http://localhost:3000/redirect
let redirectUri = 'http://localhost:3001/redirect'
app.get('/', (req, res) => {
  const authCodeUrlParameters = {
      scopes: ["user.read"],
      redirectUri: redirectUri, //接口2 redirect地址
      abc: '123asdqwe'
  };

  cca.getAuthCodeUrl(authCodeUrlParameters).then((response) => {
      // response 为微软登陆链接,前端或后端重定向到response
      res.redirect(response);
  }).catch((error) => console.log(JSON.stringify(error)));
});

app.get('/redirect', (req, res) => {
  const tokenRequest = {
      code: req.query.code, // 参数code
      scopes: ["user.read"],
      redirectUri: redirectUri, // 接口2 redirect地址
  };

  cca.acquireTokenByCode(tokenRequest).then((response) => {
      // response为个人基本信息,可做token操作
      console.log("\nResponse: \n:", response);
      res.sendStatus(200);
  }).catch((error) => {
      console.log(error);
      res.status(500).send(error);
  });
  
});

app.listen(SERVER_PORT, () => console.log(`Msal Node Auth Code Sample app listening on port ${SERVER_PORT}!`))
复制代码

eggjs环境

// controller/user.js
// jumpRedirect: 跳转链接
// msalRedirect: http://localhost:3000/redirect

const Controller = require('../core/baseController');
const msal = require('@azure/msal-node');

const config = {
  auth: {
    clientId: "******",
    authority: "******",
    clientSecret: "******"
  },
  system: {
      loggerOptions: {
          loggerCallback(loglevel, message, containsPii) {
              // console.log(message);
          },
          piiLoggingEnabled: false,
          logLevel: msal.LogLevel.Verbose,
      }
  }
};
const cca = new msal.ConfidentialClientApplication(config);

class UserController extends Controller {
  async login() {
    const { ctx } = this
    const authCodeUrlParameters = {
      scopes: ["user.read"],
      redirectUri: this.config.msalRedirect,

    };
    // get url to sign user in and consent to scopes needed for application
    let data = await new Promise((resolve, reject) => {
      cca.getAuthCodeUrl(authCodeUrlParameters).then((response) => {
        resolve(response)
      }).catch((error) => console.log(JSON.stringify(error)));
    })
    this.success({data})
  }
  async redirect() {
    const { ctx } = this
   
    const tokenRequest = {
      code: ctx.query.code,
      scopes: ["user.read"],
      redirectUri: this.config.msalRedirect,
    };
    let data = await new Promise((resolve, reject) => {
      cca.acquireTokenByCode(tokenRequest).then((response) => {
        // console.log("\nResponse: \n:", response);
        resolve(response)
      }).catch((error) => {
          console.log(error);
      });
    })
    
    ctx.redirect(`${this.config.jumpRedirect}`);
  }
}

module.exports = UserController;
复制代码

优化

重定向地址为前端页面地址,前端把微软传回来的code给后端,并请求后端接口获取用户信息

前端需要做的

login.vue
<el-link :href="thirdMicrosoft" :underline="false">
  Microsoft Azure
</el-link>
const state = reactive({
  thirdMicrosoft: import.meta.env.VITE_MICROSOFT_AZURE
});

.env
VITE_MICROSOFT_AZURE =  `https://login.microsoftonline.com/${'authority code'}/oauth2/v2.0/authorize?client_id=${client_id}&response_type=code&redirect_uri=${'前端looading页地址'/azure}t&response_mode=query&scope=offline_access%20user.read%20mail.read&state=12345`

azure.vue
<template>
  <div></div>
</template>
onMounted(async () => {
  let { code } = route.query
  if (code) {
    let res = await loginByMicrosoft({code})
    let { userInfo, token} = res.data
  } else {
    ElMessage({
      type: 'error',
      message: '登录参数错误',
      duration: 3000,
      onClose: () => {
        router.push({ path: '/login' })
      }
    })
  }
})
复制代码

后端需要做的

参考上文后端代码

猜你喜欢

转载自juejin.im/post/7017759603140067342