提供范围“离线访问”时,msal-node 中没有刷新令牌

Las*_*klu 7 node.js oauth-2.0 azure-ad-msal msal.js

我希望你能帮助我:我目前开发了一个应用程序,需要访问用户日历(outlook-calendar)来查找免费会议时段(其他用户将能够看到并选择其中一个免费时段 - 类似于calendly) 。为此,我使用msal-node进行身份验证azureAD。但我的用例需要“每次”——所有用户都可以访问日历。这就是为什么我想获得一个refresh_token。文档msal-node说我应该offline_scope在执行 OAuth 过程时提供获取刷新令牌。我的问题是我收到了 access_token 和 id_token 等,但没有刷新令牌。Azure 响应进一步显示了成功的答案,但是当我查看返回的范围时,我找不到offline_scope. 您可以在此处查看返回的范围

我应该怎么办?

我使用 cofidentalClientApplication msal-node 实例:

  const oauth2Client = MicrosoftClient.Connection
  const authCodeUrlParameters = {
    scopes: ["offline_access", "user.read"],
    forceRefresh: true,
    redirectUri: "http://localhost:3000/outlookRedirect",
  }
  try {
    console.log("GDFHGJF")
    return oauth2Client.getAuthCodeUrl(authCodeUrlParameters)
  }
Run Code Online (Sandbox Code Playgroud)

从 Azure 收到代码后,我通过以下方式处理它:

  const oauth2Client = MicrosoftClient.Connection
  const tokenRequest = {
    code: code,
    scopes: ["user.read", "offline_access"],
    forceRefresh: true,
    redirectUri: "http://localhost:3000/outlookRedirect",
    //client_secret: process.env.MICROSOFTCLIENTSECRET,
  }
  const testus = await oauth2Client.acquireTokenByCode(tokenRequest)
  const tokenRequest2 = {
    scopes: ["user.read", "offline_access"],
    forceRefresh: true,
    redirectUri: "http://localhost:3000/outlookRedirect",
    account: testus.account,
  }

  oauth2Client
    .acquireTokenSilent(tokenRequest2)
    .then((response) => {
      console.log("\nResponse: \n:", response)
    })
    .catch((error) => {
      console.log(error)
    })
  return
Run Code Online (Sandbox Code Playgroud)

我有什么错?我感谢任何形式的帮助!

提前谢谢你,卢卡斯

The*_*MCA 10

调用 'acquireTokenByCode' 后,'pca' 现在拥有刷新令牌。const tokenCache = pca.getTokenCache().serialize(); constfreshTokenObject = (JSON.parse(tokenCache)).RefreshToken constrefreshToken=refreshTokenObject[Object.keys(refreshTokenObject)[0]].secret;

\n

以下是如何获取刷新和访问令牌的完整片段。

\n
/*\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License.\n */\nconst express = require("express");\nconst msal = require('@azure/msal-node');\n\nconst SERVER_PORT = process.env.PORT || 3000;\nconst REDIRECT_URI = "http://localhost:3000/redirect";\n\n// Before running the sample, you will need to replace the values in the config, \n// including the clientSecret\nconst config = {\n    auth: {\n        clientId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX",\n        authority: "https://login.microsoftonline.com/84fb56d3-e15d-4ae1-acd7-cbf83c4c0af3",\n        clientSecret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"\n    },\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0system:\xc2\xa0{\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0loggerOptions:\xc2\xa0{\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0loggerCallback(loglevel,\xc2\xa0message,\xc2\xa0containsPii)\xc2\xa0{\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0console.log(message);\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0},\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0    piiLoggingEnabled: false,\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0    logLevel:\xc2\xa0msal.LogLevel.Verbose,\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0}\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0}\n};\n\n// Create msal application object\nconst pca = new msal.ConfidentialClientApplication(config);\n\n// Create Express App and Routes\nconst app = express();\n\napp.get('/', (req, res) => {\n    const authCodeUrlParameters = {\n        scopes: ["user.read","offline_access"],\n        redirectUri: REDIRECT_URI,\n        prompt:'consent'\n    };\n    // get url to sign user in and consent to scopes needed for application\n    pca.getAuthCodeUrl(authCodeUrlParameters).then((response) => {\n        res.redirect(response);\n    }).catch((error) => console.log(JSON.stringify(error)));\n});\n\napp.get('/redirect', (req, res) => {\n    const tokenRequest = {\n        code: req.query.code,\n        scopes: ["user.read","offline_access"],\n        redirectUri: REDIRECT_URI,\n        accessType: 'offline',\n    };\n    pca.acquireTokenByCode(tokenRequest).then((response) => {\n        const accessToken = response.accessToken;\n        const refreshToken = () => {\n            const tokenCache = pca.getTokenCache().serialize();\n            const refreshTokenObject = (JSON.parse(tokenCache)).RefreshToken\n            const refreshToken = refreshTokenObject[Object.keys(refreshTokenObject)[0]].secret;\n            return refreshToken;\n        }\n        const tokens = {\n            accessToken,\n            refreshToken:refreshToken()\n        }\n        console.log(tokens)\n        res.sendStatus(200);\n    }).catch((error) => {\n        console.log(error);\n        res.status(500).send(error);\n    });\n});\n\n\napp.listen(SERVER_PORT, () => console.log(`Msal Node Auth Code Sample app listening on port ${SERVER_PORT}!`))\n
Run Code Online (Sandbox Code Playgroud)\n

  • 不错真的很有帮助 (2认同)

小智 8

msal-node在设计上不会向最终用户公开刷新令牌。当您需要新的访问令牌时,它会在内部存储和使用。acquireTokenSilent您应该在每次需要访问令牌时调用,并msal-node通过向您返回缓存的令牌或使用刷新令牌获取新的访问令牌来管理令牌。

有关更多上下文:https ://github.com/AzureAD/microsoft-authentication-library-for-js/issues/2836