You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React SPA集成AzureAD/MSAL:登录后跳转Home页异常重定向问题

问题描述

开发React单页应用(SPA)时,使用AzureAD/MSAL实现认证功能:

  • Landing页路径为/,包含登录按钮
  • Home页路径为/home
  • 需求:未认证用户直接访问/home时自动重定向到Landing页

当前实现的重定向逻辑如下:

const navigate = useNavigate();
const { instance, inProgress } = useMsal();
const isAuthenticated = useIsAuthenticated();

useEffect(() => {
  if (inProgress === InteractionStatus.None && !isAuthenticated) {
    navigate('/');
  }
}, [inProgress, isAuthenticated, navigate]);

直接访问/home时逻辑正常,但用户首次在Landing页完成登录后,页面跳转到/home时上述重定向逻辑会触发,将用户带回Landing页,需再次点击登录才能进入/home。

完整代码:

import React, { useEffect } from 'react';
import { BrowserRouter as Router, Routes, Route, Link, useNavigate } from 'react-router-dom';
import { MsalProvider, useMsal, useIsAuthenticated } from '@azure/msal-react';
import { InteractionStatus } from '@azure/msal-browser';
import ReactDOM from 'react-dom/client';
import { PublicClientApplication } from '@azure/msal-browser';
import { msalConfig } from './js/authConfig';

const LandingPage = () => {
  const { instance } = useMsal();

  const handleLogin = () => {
    instance.loginRedirect();
  };

  return (
    <div>
      <h1>Landing Page</h1>
      <button onClick={handleLogin}>Login</button>
    </div>
  );
};

const HomePage = () => {
  const navigate = useNavigate();
  const { instance, inProgress } = useMsal();
  const isAuthenticated = useIsAuthenticated();

  useEffect(() => {
    if (inProgress === InteractionStatus.None && !isAuthenticated) {
      navigate('/');
    }
  }, [inProgress, isAuthenticated, navigate]);

  return (
    <div>
      <h1>Home Page</h1>
    </div>
  );
};

const msalInstance = new PublicClientApplication(msalConfig);

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <MsalProvider instance={msalInstance}>
      <Router>
        <Routes>
          <Route path="/" element={<LandingPage />} />
          <Route path="/home" element={<HomePage />} />
        </Routes>
      </Router>
    </MsalProvider>
  </React.StrictMode>
);

msalConfig相关配置:

redirectUri: "/home",
navigateToLoginRequestUrl: false,
原因分析

首次登录重定向到/home时,MSAL的认证状态尚未完成更新:

  • 登录重定向返回后,MSAL需要时间处理令牌、同步内部状态
  • 此时useIsAuthenticated()返回false,且inProgress已变为InteractionStatus.None,触发了重定向逻辑
解决方案

方案1:初始化时等待重定向流程完成

在应用入口处先处理MSAL的重定向Promise,确保认证状态更新后再渲染组件:

const msalInstance = new PublicClientApplication(msalConfig);

// 等待重定向认证流程结束后再渲染组件
msalInstance.handleRedirectPromise().then(() => {
  ReactDOM.createRoot(document.getElementById('root')).render(
    <React.StrictMode>
      <MsalProvider instance={msalInstance}>
        <Router>
          <Routes>
            <Route path="/" element={<LandingPage />} />
            <Route path="/home" element={<HomePage />} />
          </Routes>
        </Router>
      </MsalProvider>
    </React.StrictMode>
  );
});

方案2:优化Home页的状态判断

修改Home页的逻辑,增加加载状态判断,避免在认证流程未完成时触发重定向:

const HomePage = () => {
  const navigate = useNavigate();
  const { instance, inProgress } = useMsal();
  const isAuthenticated = useIsAuthenticated();

  useEffect(() => {
    if (inProgress === InteractionStatus.None && !isAuthenticated) {
      navigate('/');
    }
  }, [inProgress, isAuthenticated, navigate]);

  // 认证流程进行中时显示加载状态,避免页面闪烁
  if (inProgress !== InteractionStatus.None) {
    return <div>加载中...</div>;
  }

  return (
    <div>
      <h1>Home Page</h1>
    </div>
  );
};

方案3:使用路由守卫组件(推荐)

自定义路由守卫统一处理权限控制,代码更模块化:

// 自定义受保护路由组件
const ProtectedRoute = ({ children }) => {
  const isAuthenticated = useIsAuthenticated();
  const { inProgress } = useMsal();
  const navigate = useNavigate();

  useEffect(() => {
    if (inProgress === InteractionStatus.None && !isAuthenticated) {
      navigate('/');
    }
  }, [inProgress, isAuthenticated, navigate]);

  if (inProgress !== InteractionStatus.None || !isAuthenticated) {
    return <div>加载中...</div>;
  }

  return children;
};

// 修改路由配置
<Routes>
  <Route path="/" element={<LandingPage />} />
  <Route path="/home" element={
    <ProtectedRoute>
      <HomePage />
    </ProtectedRoute>
  } />
</Routes>

内容的提问来源于stack exchange,提问作者RaGe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 07:44:57