Javascript 如何从microsoft graph获取刷新令牌
我正在尝试创建outlook电子邮件自动化工具。以便it在给定时间为用户发送文件夹中的电子邮件。Microsoft允许第三方API通过auth2代表用户触发Microsoft的API。我能够检索必要的访问令牌,但我需要一个刷新令牌,以便代表用户调用代码,而不必强迫用户每小时登录一次 我目前正在使用microsoft的javascript身份验证库来接收令牌。据我所知,刷新令牌在令牌请求中似乎必须具有脱机作用域。使用下面的代码,我可以使用访问令牌响应,但仍然无法获取访问令牌Javascript 如何从microsoft graph获取刷新令牌,javascript,oauth-2.0,outlook,microsoft-graph-api,msal.js,Javascript,Oauth 2.0,Outlook,Microsoft Graph Api,Msal.js,我正在尝试创建outlook电子邮件自动化工具。以便it在给定时间为用户发送文件夹中的电子邮件。Microsoft允许第三方API通过auth2代表用户触发Microsoft的API。我能够检索必要的访问令牌,但我需要一个刷新令牌,以便代表用户调用代码,而不必强迫用户每小时登录一次 我目前正在使用microsoft的javascript身份验证库来接收令牌。据我所知,刷新令牌在令牌请求中似乎必须具有脱机作用域。使用下面的代码,我可以使用访问令牌响应,但仍然无法获取访问令牌 const令牌请求=
const令牌请求={
范围:[
"https://graph.microsoft.com/Mail.ReadWrite",
"https://graph.microsoft.com/mail.send",
"https://graph.microsoft.com/offline_access"
]
};
常量主机名=”http://localhost:5000";
const backendserveraddress=”http://localhost:8050";
var xhr=new XMLHttpRequest();
xhr.open(“POST”,backendserveraddress,true);
setRequestHeader(“内容类型”、“应用程序/json”);
常量msalConfig={
认证:{
clientId:“某物”,
重定向URI:hostname+“/homepage/index.html”
}
};
var loginRequest={
作用域:[“Mail.ReadWrite”、“Mail.send”、“offline_access”]//可选数组
};
const TOKEN_ID=“TOKEN_ID”;
const msalInstance=新的Msal.UserAgentApplication(msalConfig);
msalInstance.HandlerRedirectCallback((错误,响应)=>{
log(“重定向回调完成”);
});
异步函数redirectToDashboard(){
日志(“重定向到仪表板”);
//var response=wait requestTokenSilent();
var反应;
如果(!response | |!response.status==200){
response=wait requestTokenPopup();
}
if(response&&response.status==200){
发送(
JSON.stringify({
名字:“某物”,
姓:“某物”,
accessToken:“某物”
})
);
location.href=主机名;
}否则{
console.log(“无法获取令牌”);
}
}
函数重定向登录(){
log(“调用重定向”);
如果(!msalInstance.getAccount()){
返回msalInstance
.loginRedirect(loginRequest)
。然后(响应=>{
控制台日志(响应);
返回响应;
})
.catch(错误=>{
log(“身份验证错误:”,err);
});
}
if(msalInstance.getAccount()){
重定向到仪表板();
}
}
异步函数requestTokenSilent(){
console.log(“requestTokenSilent”);
if(msalInstance.getAccount()){
返回msalInstance
.acquireTokenSilent(令牌请求)
。然后(响应=>{
setItem(TOKEN\u ID,response.accessToken);
日志(“已到达响应:”,响应);
决心(回应);
})
.catch(错误=>{
if(err.name==“InteractionRequiredAuthError”){
警报(“身份验证失败,请重试”);
}
});
}
}
异步函数requestTokenPopup(){
console.log(“requestTokenPopup”);
if(msalInstance.getAccount()){
返回msalInstance
.acquireTokenPopup(令牌请求)
。然后(响应=>{
setItem(TOKEN\u ID,response.accessToken);
返回响应;
})
.catch(错误=>{
控制台日志(err);
if(err.name==“InteractionRequiredAuthError”){
警报(“身份验证失败,请重试”);
}
});
}
}
首先,我不擅长JavaScript,但在我看来,您似乎没有拿出刷新令牌。刷新令牌是长期存在的,但是在请求新令牌时,您必须在收到新的访问令牌时更新刷新令牌,因为授权服务器可能会发出新令牌
我在这篇文章中找到了很多帮助。
首先,我不擅长JavaScript,但在我看来,您似乎没有拿出刷新令牌。刷新令牌是长期存在的,但是在请求新令牌时,您必须在收到新的访问令牌时更新刷新令牌,因为授权服务器可能会发出新令牌 我在这篇文章中找到了很多帮助。
我使用的是msal的v1版本。V1版本不再支持刷新令牌。我被告知msal v2支持刷新令牌,但它目前处于测试阶段。我使用的是msal的v1版本。V1版本不再支持刷新令牌。我听说msal v2支持刷新令牌,但它目前处于测试阶段。不支持获取访问令牌。此流根本不返回刷新令牌,因为刷新令牌在隐式流中没有用途。刷新是通过一个隐藏请求完成的。从上面的链接: 隐式授权不提供刷新令牌。id_令牌和access_令牌都将在短时间后过期,因此您的应用程序必须准备定期刷新这些令牌。要刷新任一类型的令牌,可以使用prompt=none参数从上面执行相同的隐藏iframe请求,以控制identity platform的行为。如果要接收新的id_令牌,请确保在响应_type和scope=openid中使用id_令牌以及nonce参数 当您调用
requestTokenSilent
时,如果当前访问令牌过期,MSAL.js将自动为您执行此操作
您需要一个刷新令牌,因为您的真正目标是让后端服务器进程访问该图。这是行不通的。相反,您需要使用。您可以在这里阅读所有细节,但高级总结是:
- JavaScript前端使用MSAL.js通过隐式流为后端web API获取令牌。它通过调用将
头中的此令牌发送到后端授权
- 您的后端使用代表流将该令牌交换为acc
const tokenRequest = { scopes: [ "https://graph.microsoft.com/Mail.ReadWrite", "https://graph.microsoft.com/mail.send", "https://graph.microsoft.com/offline_access" ] }; const hostname = "http://localhost:5000"; const backendServerAdress = "http://localhost:8050"; var xhr = new XMLHttpRequest(); xhr.open("POST", backendServerAdress, true); xhr.setRequestHeader("Content-Type", "application/json"); const msalConfig = { auth: { clientId: "something", redirectUri: hostname + "/homepage/index.html" } }; var loginRequest = { scopes: ["Mail.ReadWrite", "mail.send", "offline_access"] // optional Array<string> }; const TOKEN_ID = "token_id"; const msalInstance = new Msal.UserAgentApplication(msalConfig); msalInstance.handleRedirectCallback((error, response) => { console.log("redirect callback done"); }); async function redirectToDashboard() { console.log("redirect to dashboard"); // var response = await requestTokenSilent(); var response; if (!response || !response.status == 200) { response = await requestTokenPopup(); } if (response && response.status == 200) { xhr.send( JSON.stringify({ firstname: "something", lastname: "something", accessToken: "something" }) ); location.href = hostname; } else { console.log("Unable to acquire token"); } } function redirectLogin() { console.log("redirect called"); if (!msalInstance.getAccount()) { return msalInstance .loginRedirect(loginRequest) .then(response => { console.log(response); return response; }) .catch(err => { console.log("Authentication error: ", err); }); } if (msalInstance.getAccount()) { redirectToDashboard(); } } async function requestTokenSilent() { console.log("requestTokenSilent"); if (msalInstance.getAccount()) { return msalInstance .acquireTokenSilent(tokenRequest) .then(response => { localStorage.setItem(TOKEN_ID, response.accessToken); console.log("response reached: ", response); resolve(response); }) .catch(err => { if (err.name === "InteractionRequiredAuthError") { alert("Authentication failed try again"); } }); } } async function requestTokenPopup() { console.log("requestTokenPopup"); if (msalInstance.getAccount()) { return msalInstance .acquireTokenPopup(tokenRequest) .then(response => { localStorage.setItem(TOKEN_ID, response.accessToken); return response; }) .catch(err => { console.log(err); if (err.name === "InteractionRequiredAuthError") { alert("Authentication failed try again"); } }); } }