【问题标题】: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)
}
})
})
}
谢谢