在 Azure(Microsoft graph)委托流程中处理刷新令牌

问题描述 投票:0回答:1

我正在开发一个项目,需要在用户的 Outlook 日历中创建事件。要求是将工作检查日期添加到相关用户的日历中。此外,用户应该能够在其日历上手动创建事件。

我所实施的:

  1. 用户将被重定向到微软登录页面。
  2. 登录后,微软将向我们提供该用户的访问令牌。
  3. 使用 getTokenCache 我们正在获取该用户的刷新令牌。

这是代码:

路线:

router.get('/login', getAuthCodeUrl);
router.get('/callback', handleCallback);

控制器:

const { ConfidentialClientApplication } = require('@azure/msal-node');

// TEST APP
const clientId = '945bf51b-xxxx-c5a83898b4b8';
const clientSecret = '9mV8Q~xxxx.zf9GqLGt95UUJ_bGdcp';

const msalConfig = {
  auth: {
    clientId: clientId,
    authority: `https://login.microsoftonline.com/common`,
    clientSecret: clientSecret,
  },
};

const redirectUri = 'http://localhost:3000/api/callback';

const scopes = [
  'User.Read',
  'Calendars.ReadWrite',
  'offline_access',
  'openid',
  'profile',
];

const cca = new ConfidentialClientApplication(msalConfig);

const getAuthCodeUrl = async (req, res) => {
  const authCodeUrlParameters = {
    scopes,
    redirectUri,
  };

  const authUrl = await cca.getAuthCodeUrl(authCodeUrlParameters);
  console.log('authUrl: ', authUrl);
  res.redirect(authUrl);
};

const handleCallback = async (req, res) => {
  const tokenRequest = {
    scopes,
    code: req.query.code,
    redirectUri,
    accessType: 'offline',
  };

  try {
    const authResult = await cca.acquireTokenByCode(tokenRequest);

    const accessToken = authResult.accessToken;

    const refreshToken = () => {
      const tokenCache = cca.getTokenCache().serialize();
      const refreshTokenObject = JSON.parse(tokenCache).RefreshToken;
      const refreshToken =
        refreshTokenObject[Object.keys(refreshTokenObject)[0]].secret;
      return refreshToken;
    };

    const tokens = {
      accessToken,
      refreshToken: refreshToken(),
    };

    console.log('tokens: ', tokens);

    // Handle token result, store tokens, etc.
    res.send('Authentication successful. You can close this window.');
  } catch (error) {
    console.error('Error obtaining access token:', error);
    res.status(500).send('Error obtaining access token');
  }
};

这是我的问题:

  1. 在我们的refreshToken函数中,我们没有传递任何与该用户相关的东西。我很困惑 MSAL 如何获取该用户而不是其他用户的刷新令牌?
  2. “访问令牌最多只能刷新 90 天”,我在研究时在很多地方读到过这一点。 用户是否需要每 90 天登录一次?
  3. 我们可以在不需要用户再次登录的情况下获得新的刷新令牌吗?
  4. 我们如何知道访问令牌是否过期?我们是否需要调用配置文件(或任何其他)API 来检查访问令牌的过期情况?
node.js outlook azure-active-directory microsoft-graph-api azure-ad-msal
1个回答
0
投票
  • 如果您正在使用 MSAL 库,则无需传递任何用户信息,因为在初始身份验证流程中,MSAL 会生成刷新令牌并将其存储在其令牌缓存中。
  • MSAL 库根据身份验证上下文了解刷新令牌属于哪个用户。
  try {
    const authResult = await cca.acquireTokenByCode(tokenRequest);

    const accessToken = authResult.accessToken;

    const refreshToken = () => {
      const tokenCache = cca.getTokenCache().serialize();
      const refreshTokenObject = JSON.parse(tokenCache).RefreshToken;
      const refreshToken =
        refreshTokenObject[Object.keys(refreshTokenObject)[0]].secret;
      return refreshToken;
    };
  • 当您调用
    cca.getTokenCache().serialize()
    时,它会返回序列化令牌缓存,其中包括用户的刷新令牌。

注意:访问令牌的刷新期限最长为 90 天。参考这个MsDoc

  • 刷新令牌可以被撤销,因此应用程序必须通过 将用户发送到交互式登录提示以再次登录来优雅地处理登录服务的拒绝。
  • MSAL 缓存存储刷新令牌,因此无需再次登录。
  • 如果访问令牌未过期,MSAL 将返回带有相关令牌的响应;如果访问令牌已过期且刷新令牌有效,则它将使用刷新令牌检索新的访问令牌并返回响应。
  • 因此无需调用配置文件(或任何其他)API 来检查访问令牌的过期情况。您还可以检查
    expires_in
    属性。

enter image description here

参考:

开发人员处的 microsoft-authentication-library-for-js/lib/msal-browser/docs/token-lifetimes.md · AzureAD/microsoft-authentication-library-for-js · GitHub

© www.soinside.com 2019 - 2024. All rights reserved.