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

如何在React.js应用中获取Azure AD已登录用户的最后登录时间?

在React应用中通过Azure AD获取用户最后登录时间并更新数据库

方法一:直接解析Azure AD返回的ID Token(推荐轻量方案)

Azure AD在用户登录成功后返回的ID Token中包含auth_time声明,这个字段就是用户完成身份认证的时间戳(Unix时间戳,单位秒),完全符合“最后登录时间”的需求。

实现步骤:

  • 在React中用MSAL.js获取当前登录用户的ID Token,解码后提取auth_time字段
  • 将Unix时间戳转换为标准ISO格式,通过后端接口更新数据库中对应用户的最后登录时间

React代码示例(基于MSAL.js v2):

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

const handleLoginSuccess = () => {
  const { instance, accounts } = useMsal();
  const currentAccount = accounts[0];

  const updateLastLogin = async () => {
    if (!currentAccount) return;

    // 静默获取ID Token
    const tokenResponse = await instance.acquireTokenSilent({
      account: currentAccount,
      scopes: ["openid", "profile"]
    });

    // 解码ID Token(JWT的第二部分)
    const decodedToken = JSON.parse(atob(tokenResponse.idToken.split('.')[1]));
    // 转换为ISO时间格式
    const lastLoginTime = new Date(decodedToken.auth_time * 1000).toISOString();

    // 调用后端接口更新数据库
    await fetch("/api/user/update-last-login", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        userId: currentAccount.username, // 用用户唯一标识(如邮箱)匹配数据库记录
        lastLoginTime
      })
    });
  };

  useEffect(() => {
    updateLastLogin();
  }, [currentAccount]);
};

后端更新示例(Node.js + MongoDB):

app.post("/api/user/update-last-login", async (req, res) => {
  const { userId, lastLoginTime } = req.body;
  
  try {
    // 根据userId(如邮箱)更新用户的lastLoginTime字段
    await UserModel.updateOne(
      { email: userId },
      { $set: { lastLoginTime } }
    );
    res.status(200).json({ success: true });
  } catch (err) {
    res.status(500).json({ success: false, error: err.message });
  }
});

方法二:调用Microsoft Graph API获取登录日志(适合批量/详细场景)

如果需要获取更完整的登录历史,或者批量更新用户最后登录时间,可以调用Microsoft Graph的signInLogs接口,获取用户最新的登录记录。

注意事项:

  • 必须由后端发起调用(前端无法获取足够权限)
  • 需为Azure AD应用申请AuditLog.Read.All应用权限(需要管理员同意)
  • 登录日志存在15-30分钟的延迟,不适合实时更新场景

后端代码示例(Node.js + Microsoft Graph Client):

const { Client } = require("@microsoft/microsoft-graph-client");
const { ClientSecretCredential } = require("@azure/identity");
const { TokenCredentialAuthenticationProvider } = require("@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials");

// 初始化Graph客户端
const credential = new ClientSecretCredential(
  process.env.AZURE_TENANT_ID,
  process.env.AZURE_CLIENT_ID,
  process.env.AZURE_CLIENT_SECRET
);

const authProvider = new TokenCredentialAuthenticationProvider(credential, {
  scopes: ["https://graph.microsoft.com/.default"]
});

const graphClient = Client.initWithMiddleware({ authProvider });

// 获取用户最新登录时间
async function getUserLatestLoginTime(userId) {
  try {
    const signInLogs = await graphClient
      .api(`/users/${userId}/signInLogs`)
      .top(1) // 只取最新一条
      .orderBy("createdDateTime desc")
      .get();

    return signInLogs.value.length > 0 
      ? signInLogs.value[0].createdDateTime 
      : null;
  } catch (err) {
    console.error("获取登录日志失败:", err);
    return null;
  }
}

// 更新数据库
async function updateUserLastLogin(userId) {
  const lastLoginTime = await getUserLatestLoginTime(userId);
  if (lastLoginTime) {
    await UserModel.updateOne(
      { azureUserId: userId },
      { $set: { lastLoginTime } }
    );
  }
}

关键注意点

  • auth_time vs 登录日志:auth_time是实时的,每次用户完成认证(包括SSO登录)都会更新,适合实时记录最后登录时间;登录日志适合回溯历史或批量统计。
  • 刷新Token场景:如果用户通过刷新Token获取新凭证而未重新认证,auth_time不会更新,这符合“最后登录”的定义(用户主动认证的时间),而非“最后访问”时间。
  • 权限控制:Graph API的AuditLog.Read.All权限需要管理员同意,部署前需确认租户权限配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 03:05:15