如何在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_timevs 登录日志:auth_time是实时的,每次用户完成认证(包括SSO登录)都会更新,适合实时记录最后登录时间;登录日志适合回溯历史或批量统计。- 刷新Token场景:如果用户通过刷新Token获取新凭证而未重新认证,
auth_time不会更新,这符合“最后登录”的定义(用户主动认证的时间),而非“最后访问”时间。 - 权限控制:Graph API的
AuditLog.Read.All权限需要管理员同意,部署前需确认租户权限配置。
内容的提问来源于stack exchange,提问作者Profer
相关产品推荐
相关产品推荐

