如何阻止基于Azure认证的Web应用登出后自动登录?
问题描述
我正在开发一款使用Microsoft账号实现登录/登出功能的Web应用,目前遇到Microsoft Azure认证相关问题:用户点击登出按钮后虽完成登出,但会自动重新登录至该Web应用。我期望的行为是:用户登出后跳转回应用,仅当点击登录按钮时才触发登录操作。尝试过其他方案,但问题依旧。
相关代码
MSAL配置代码
const branchUrl = new RegExp(/\/BUY-\d{4}/).exec(window.location.pathname)?.[0] ?? ''; const msalConfig: Configuration = { auth: { authority: `https://login.microsoftonline.com/${process.env.REACT_APP_AZURE_TENANT_ID}`, clientId: `${process.env.REACT_APP_AZURE_CLIENT_ID}`, redirectUri: `${window.location.origin}${branchUrl}`, postLogoutRedirectUri: `${window.location.origin}${branchUrl}`, navigateToLoginRequestUrl: false, }, cache: { cacheLocation: 'localStorage', }, }; const msalLoginRequest: PopupRequest = { scopes: [ 'User.Read', ], }; const msalInstance = new PublicClientApplication(msalConfig); const accounts = msalInstance.getAllAccounts(); if (accounts.length > 0) { msalInstance.setActiveAccount(accounts[0]); } msalInstance.addEventCallback((event: EventMessage) => { if (event.eventType === EventType.LOGIN_SUCCESS && event.payload) { const payload = event.payload as AuthenticationResult; const account = payload.account; msalInstance.setActiveAccount(account); } }); export const msalService = { msalInstance, msalLoginRequest, };
组件逻辑代码
export const Header = ({ styleNumber, setStyleNumber, generalQuery, setGeneralQuery }: HeaderProps): ReactElement => { const { login } = useContext(AuthorizationContext); const { instance, accounts } = useMsal(); const isAuthenticated = useIsAuthenticated(); const account = useAccount(accounts[0] || {}); const handleOnSignIn = (): void =>{ login(); }; const handleSignOut = (): void => { instance.logoutRedirect({ account, }).then(() => { }) .catch((error) => { // Handle logout error if needed console.error('Logout error:', error); }); }; return ( <Box sx={{ height: '24px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', paddingLeft: 10, flex: 1, }} > {isAuthenticated ? ( <Box sx={{ display: 'flex', alignItems: 'center', }} > <UserInfo /> <Button key="signOut-button" size="large" sx={{ marginLeft: 2 }} onClick={handleSignOut}> Sign Out </Button> <Button component="label" variant="contained" startIcon={<PlusIcon />} sx={{ marginLeft: 2 }} onClick={handleCreateCertificate}> Create a new certificate </Button> </Box> ) : ( <Button key="signIn-button" size="large" sx={{ marginLeft: 2 }} onClick={handleOnSignIn}> Sign In </Button> )} </Box> ); };
解决方案
出现自动重新登录的核心原因是MSAL初始化时自动读取缓存账号、浏览器会话静默续登,或登出未彻底清理会话。以下是针对性修改:
修改登出逻辑,彻底清理会话与缓存
更新handleSignOut函数,添加会话终止参数并手动清除账号缓存:const handleSignOut = (): void => { instance.logoutRedirect({ account, postLogoutRedirectUri: `${window.location.origin}${branchUrl}`, maintainSession: false, // 彻底终止Microsoft会话 }).then(() => { instance.removeAllAccounts(); // 清除MSAL账号缓存 window.localStorage.removeItem(`msal.${process.env.REACT_APP_AZURE_CLIENT_ID}`); // 精准清理MSAL缓存项 }).catch((error) => { console.error('Logout error:', error); }); };移除初始化时自动激活账号的逻辑
删除原代码中自动设置活跃账号的片段,仅在登录成功事件中设置活跃账号:// 移除这段代码 // const accounts = msalInstance.getAllAccounts(); // if (accounts.length > 0) { // msalInstance.setActiveAccount(accounts[0]); // } // 保留原有的登录成功回调即可 msalInstance.addEventCallback((event: EventMessage) => { if (event.eventType === EventType.LOGIN_SUCCESS && event.payload) { const payload = event.payload as AuthenticationResult; const account = payload.account; msalInstance.setActiveAccount(account); } });完善MSAL配置,避免自动登录触发
在msalConfig的auth部分添加logoutUri配置:const msalConfig: Configuration = { auth: { authority: `https://login.microsoftonline.com/${process.env.REACT_APP_AZURE_TENANT_ID}`, clientId: `${process.env.REACT_APP_AZURE_CLIENT_ID}`, redirectUri: `${window.location.origin}${branchUrl}`, postLogoutRedirectUri: `${window.location.origin}${branchUrl}`, logoutUri: `${window.location.origin}${branchUrl}`, // 新增配置,确保登出跳转路径正确 navigateToLoginRequestUrl: false, }, cache: { cacheLocation: 'localStorage', }, };确认登录逻辑仅主动触发
确保AuthorizationContext中的login函数仅在用户点击登录按钮时执行,无页面加载时的自动调用:// 示例login函数实现 const login = () => { msalInstance.loginRedirect(msalLoginRequest); // 或使用弹窗登录:msalInstance.loginPopup(msalLoginRequest); };
通过以上修改,登出时会彻底清除会话与缓存,初始化阶段不会自动激活账号,从而避免登出后自动重新登录的问题,确保只有用户主动点击登录按钮时才触发登录流程。
内容的提问来源于stack exchange,提问作者Jdeveloper
相关产品推荐
相关产品推荐

