【问题标题】:CORS issue while getting access token using client_credentials using javascript/reactjs from microsoft graph /token?使用 microsoft graph /token 中的 javascript/reactjs 使用 client_credentials 获取访问令牌时出现 CORS 问题?
【发布时间】:2021-07-09 10:23:02
【问题描述】:

我需要使用 fetch() 方法获取访问令牌,但我无法使用 fetch() 方法这样做。尝试允许所有人使用 Cors-policy 或 cross-Access-Origin,但似乎没有任何效果。

CORS 策略已阻止从源“http://localhost:3050”访问“https://login.microsoftonline.com/xxxxxxxxxxxxxxxxxxxxxxxxxxx/common/oauth2/v2.0/token”获取:请求的资源上不存在“Access-Control-Allow-Origin”标头。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。

graphService.ts:81 POST https://login.microsoftonline.com//common/oauth2/v2.0/token net::ERR_FAILED

提前致谢:)

【问题讨论】:

    标签: javascript oauth cors fetch microsoft-graph-api


    【解决方案1】:

    您收到 cors 错误,因为当您在使用 client_credentials 时包含 Origin 标头时 Azure AD 拒绝请求。首先,您以错误的方式使用 client_credentials 流程。 考虑阅读有关客户端凭据流的guide,以帮助您了解为什么它更适合服务器端/守护程序应用程序。

    要查看错误,只需将 Origin 标头添加到邮递员并再次执行请求。

    另请阅读 here 以了解您可以使用的 oauth2 流程

    对于您的情况,您可以使用authorization code flow,因为您有一个 SPA。

    【讨论】:

      【解决方案2】:

      导致问题的不是流程或配置。真正的问题是前端或 SPA。如果您想通过客户端凭据流调用 API 以获取令牌,您必须遵循我猜是强制性的两种方法中的任何一种。

      1.守护程序服务

      2.服务器端实现

      我已经使用 Node 调用了 API,并且配置与文档中提到的相同,现在可以正常工作了。 msal-node npm包是调用api的替代方案,也可以自己调用graph api。

      async getAppTokenFromAzureAD() : Promise <any | Error> {
              const requestHeaders : HeadersInit = new Headers();
              var details = {
                  'client_secret' : 'xxxxxxxxxxxxxxxxxxxxxx',
                  'client_id':'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
                  'scope':'https://graph.microsoft.com/.default',
                  'grant_type':"client_credentials"
              };
              
              let formBody:any = [];
              for (var property in details) {
                var encodedKey = encodeURIComponent(property);
                var encodedValue = encodeURIComponent(details[property]);
                formBody.push(encodedKey + "=" + encodedValue);
              }
              formBody = formBody.join("&");
              requestHeaders.set('Content-Type', 'application/x-www-form-urlencoded');
              requestHeaders.set('Host','login.microsoftonline.com');
              return new Promise((resolve,reject)=>{
                  this.connection.transaction(async (entityManager) => {
                      try {
                          let tokenResponse = fetch('https://login.microsoftonline.com/xxxxxxxxxxxxxxxxxxxx9/oauth2/v2.0/token',{
                              method : 'POST',
                              headers : requestHeaders,
                              body : formBody
      
                          })
                          tokenResponse.then(data=>data.json()).then(responses=>{
                              resolve({
                                  statusMessage: getMessageByKey('apllicationTokenSuccess'),
                                  responses,
                              })
                          }).catch(error=>{
                              reject(error);
                          })
                      } catch (error) {
                          reject(error)
                      }
                  })
              })
          } 

      谢谢

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-08
        • 1970-01-01
        相关资源
        最近更新 更多