React集成MSAL时loginPopup登录弹窗无法自动关闭问题
React + MSAL 登录弹窗无法自动关闭问题
我正在用React结合MSAL实现登录功能,目标是获取MSAL生成的token用于后续fetch请求。调用loginPopup()打开登录弹窗,用户完成微软账号登录后,弹窗本该自动关闭,但实际没关,反而跳转到了我的默认页面。
使用的MSAL版本:@azure/msal-browser": "^3.1.0"
MSAL配置
const MsalConfig = { auth: { clientId: "THIS_IS_SECRET", authority: "https://login.microsoftonline.com/THIS_IS_SECRET", redirectUri: "https://myappservicetests.azurewebsites.net/", // 替换为你的重定向URI }, cache: { cacheLocation: "localStorage", storeAuthStateInCookie: false, }, system: { loggerOptions: { loggerCallback: (level, message, containsPii) => { if (containsPii) { return; } switch (level) { case LogLevel.Error: console.error(message); return; case LogLevel.Warning: console.warn(message); return; } } } } };
获取Token的代码
const GetLoginToken = async () => { const msalInstance = new PublicClientApplication(ClientSettings.MsalConfig); await msalInstance.initialize(); const loginRequest = { scopes: ["user.read"], }; const accounts = msalInstance.getAllAccounts(); if (accounts.length > 0) { const accessTokenRequest = { scopes: ["user.read"], account: accounts[0], }; try { const tokenResponse = await msalInstance.acquireTokenSilent(accessTokenRequest); localStorage.setItem("tokenAZWebAppTest", tokenResponse.accessToken); return tokenResponse.accessToken; } catch (error) { // 处理静默获取token错误 console.error("静默获取token出错:", error); } } else { try { msalInstance.addEventCallback((event) => { if (event.eventType === EventType.LOGIN_SUCCESS) { window.close(); } }); const response = await msalInstance.loginPopup(loginRequest); console.log("登录响应: ", response); if (response.account) { const tokenRequest = { scopes: ["user.read"], account: response.account, }; const tokenResponse = await msalInstance.acquireTokenSilent(tokenRequest); localStorage.setItem("tokenAZWebAppTest", tokenResponse.accessToken); return tokenResponse.accessToken; } } catch (error) { console.error("登录出错:", error); } } return null; }
问题原因及解决办法
1. 重定向URI配置错误
MSAL弹窗登录成功后会跳转到配置的redirectUri,如果该URI是应用首页,弹窗就会加载首页而非关闭。解决步骤:
- 新增一个空白回调页(如
popup-callback.html)作为弹窗的重定向目标,地址示例:https://myappservicetests.azurewebsites.net/popup-callback.html - 在Azure AD应用注册的"身份验证"页面,将该URI添加到"单页应用(SPA)"的重定向URI列表中
- 修改MsalConfig中的
redirectUri为这个回调页地址
2. 回调页处理逻辑
创建popup-callback.html,无需复杂UI,只需完成MSAL回调后自动关闭弹窗:
<!DOCTYPE html> <html> <head> <title>登录回调</title> </head> <body> <script type="text/javascript" src="https://alcdn.msauth.net/browser/3.1.0/js/msal-browser.min.js"></script> <script type="text/javascript"> const msalConfig = { auth: { clientId: "YOUR_CLIENT_ID", authority: "https://login.microsoftonline.com/YOUR_TENANT_ID" } }; const msalInstance = new msal.PublicClientApplication(msalConfig); msalInstance.handleRedirectPromise().then(() => { window.close(); }).catch(err => { console.error("回调处理出错:", err); }); </script> </body> </html>
3. 优化登录代码逻辑
原代码通过addEventCallback调用window.close()的方式不可靠,loginPopup本身是异步方法,成功后会自动处理回调。简化后的代码如下:
const GetLoginToken = async () => { const msalInstance = new PublicClientApplication(ClientSettings.MsalConfig); await msalInstance.initialize(); const loginRequest = { scopes: ["user.read"], }; const accounts = msalInstance.getAllAccounts(); if (accounts.length > 0) { try { const tokenResponse = await msalInstance.acquireTokenSilent({ scopes: ["user.read"], account: accounts[0], }); localStorage.setItem("tokenAZWebAppTest", tokenResponse.accessToken); return tokenResponse.accessToken; } catch (error) { console.error("静默获取token出错:", error); // 静默失败时尝试弹窗获取 try { const tokenResponse = await msalInstance.acquireTokenPopup({ scopes: ["user.read"], account: accounts[0], }); localStorage.setItem("tokenAZWebAppTest", tokenResponse.accessToken); return tokenResponse.accessToken; } catch (popupErr) { console.error("弹窗获取token出错:", popupErr); } } } else { try { const loginResponse = await msalInstance.loginPopup(loginRequest); if (loginResponse.account) { const tokenResponse = await msalInstance.acquireTokenSilent({ scopes: ["user.read"], account: loginResponse.account, }); localStorage.setItem("tokenAZWebAppTest", tokenResponse.accessToken); return tokenResponse.accessToken; } } catch (error) { console.error("登录出错:", error); } } return null; }
4. 检查Azure AD应用注册配置
- 确认应用注册中已添加回调页URI,且类型为"单页应用(SPA)"
- 确保
User.Read权限已添加,若需要管理员权限需完成同意操作
内容的提问来源于stack exchange,提问作者Dr oscar
相关产品推荐
相关产品推荐

