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

React集成Azure AD:刷新令牌机制及会话过期重定向登录求助

React集成Azure AD:Refresh Token机制与会话过期自动重定向实现

Azure AD Refresh Token 工作机制

  • 用户首次通过Azure AD登录后,若请求了offline_access权限,服务端会返回Access Token和Refresh Token
  • Access Token有效期较短(默认1小时),用于调用受保护的API;Refresh Token有效期更长(由Azure AD策略决定,最长90天),专门用于在Access Token过期时获取新的Access Token
  • 当Access Token过期,应用可通过MSAL库自动调用Azure AD的令牌端点,用Refresh Token换取新的Access Token,同时可能返回新的Refresh Token(滚动刷新,延长有效期)
  • 若Refresh Token失效(如用户密码变更、账号禁用、超过有效期),则无法继续静默获取令牌,必须引导用户重新登录

React中实现会话过期自动重定向

以下基于官方推荐的@azure/msal-react和@azure/msal-browser库实现:

1. 初始化MSAL实例

import { PublicClientApplication } from '@azure/msal-browser';

const msalConfig = {
  auth: {
    clientId: '你的Azure AD应用Client ID',
    authority: 'https://login.microsoftonline.com/你的租户ID',
    redirectUri: '应用回调地址(需在Azure AD后台配置)'
  }
};

export const msalInstance = new PublicClientApplication(msalConfig);

2. 监听令牌获取失败事件

通过MSAL的事件回调捕获令牌失效场景,自动触发登录重定向:

import { EventType } from '@azure/msal-browser';

msalInstance.addEventCallback((event) => {
  if (event.eventType === EventType.ACQUIRE_TOKEN_FAILURE) {
    // 判断是否为refresh token失效或令牌过期导致的失败
    const isTokenInvalid = event.error.errorMessage.includes('invalid_grant') || event.error.errorMessage.includes('token_expired');
    if (isTokenInvalid) {
      msalInstance.loginRedirect();
    }
  }
});

3. 路由守卫验证令牌状态

在受保护路由跳转前检查令牌有效性,失效则重定向登录:

import { useMsal } from '@azure/msal-react';
import { Navigate } from 'react-router-dom';

export const ProtectedRoute = ({ children }) => {
  const { instance, accounts } = useMsal();
  const activeAccount = accounts[0];

  // 无活跃账号直接跳转登录
  if (!activeAccount) {
    return <Navigate to="/" replace />;
  }

  // 检查令牌是否过期
  const tokenClaims = instance.getActiveAccount()?.idTokenClaims;
  const isTokenExpired = tokenClaims?.exp * 1000 < Date.now();

  if (isTokenExpired) {
    // 尝试静默刷新令牌,失败则重定向登录
    instance.acquireTokenSilent({
      account: activeAccount,
      scopes: ['openid', 'profile', 'offline_access'] // 必须包含offline_access才能获取refresh token
    }).catch(() => {
      instance.loginRedirect();
    });
  }

  return children;
};

4. 定时检查令牌有效期

设置定时器提前检测令牌状态,避免用户操作时突然过期:

import { useEffect } from 'react';
import { useMsal } from '@azure/msal-react';

export const TokenExpiryChecker = () => {
  const { instance, accounts } = useMsal();

  useEffect(() => {
    const checkExpiry = () => {
      const activeAccount = accounts[0];
      if (!activeAccount) return;

      const tokenClaims = instance.getAccountByUsername(activeAccount.username)?.idTokenClaims;
      if (!tokenClaims) return;

      // 提前5分钟触发检查,预留刷新时间
      const warnTime = tokenClaims.exp * 1000 - 5 * 60 * 1000;
      if (Date.now() >= warnTime) {
        instance.acquireTokenSilent({
          account: activeAccount,
          scopes: ['openid', 'profile', 'offline_access']
        }).catch(() => {
          instance.loginRedirect();
        });
      }
    };

    // 每分钟执行一次检查
    const interval = setInterval(checkExpiry, 60 * 1000);
    return () => clearInterval(interval);
  }, [instance, accounts]);

  return null;
};

注意事项

  • 必须在Azure AD应用注册后台配置正确的redirectUri,并确保应用已获得offline_access权限
  • 不要手动存储或操作Refresh Token,MSAL库会自动管理令牌缓存
  • 静默刷新失败时,务必触发重定向登录,此时Refresh Token已无法使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 02:30:44