I'm using Azure AD for authentication in a React.js application. I need to retrieve the last login time of the currently logged-in user and store it in the database for use on the user management page.
Users are already being saved in the database, and I want to track the last login timestamp for each user. However, since authentication is handled by Azure AD, I don't have direct control over the login process to record this timestamp myself. Therefore, I need to fetch the user's last login time from Azure AD.
To retrieve the last login date & time for the logged in user you can make use of Microsoft Graph API query.
According to this MsDoc, the signed-in user must have a supported Microsoft Entra role such as Security Reader or Reports Reader and the application must be granted with AuditLog.Read.All
Granted AuditLog.Read.All
delegated API permission:
Configured redirect URL under SPA:
Assigned Global Reader role (active assignment) to the user:
Now used the below code to fetch the last login date & time for the logged in user:
authConfig.js
export const msalConfig = {
auth: {
clientId: "ClientID",
authority: "https://login.microsoftonline.com/TenantID",
redirectUri: "http://localhost:3000",
},
cache: {
cacheLocation: "localStorage",
},
};
export const loginRequest = {
scopes: ["User.Read", "AuditLog.Read.All"],
prompt: "select_account",
};
index.js
// src/index.js
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { PublicClientApplication } from "@azure/msal-browser";
import { MsalProvider } from "@azure/msal-react";
import { msalConfig } from "./authConfig";
const msalInstance = new PublicClientApplication(msalConfig);
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<MsalProvider instance={msalInstance}>
<App />
</MsalProvider>
);
App.js
// src/App.js
import React from "react";
import { useMsal, useIsAuthenticated } from "@azure/msal-react";
import { loginRequest } from "./authConfig";
import axios from "axios";
function App() {
const { instance, accounts } = useMsal();
const isAuthenticated = useIsAuthenticated();
const handleLogin = async () => {
try {
await instance.loginPopup(loginRequest);
} catch (error) {
console.error("Login failed", error);
}
};
const handleLogout = async () => {
try {
const account = accounts[0];
await instance.logoutPopup({ account });
} catch (error) {
console.error("Logout failed", error);
}
};
const getSignInActivity = async () => {
const account = accounts[0];
if (!account) return;
try {
const response = await instance.acquireTokenSilent({
...loginRequest,
account,
});
const graphResponse = await axios.get(
"https://graph.microsoft.com/v1.0/me?$select=id,signInActivity",
{
headers: {
Authorization: `Bearer ${response.accessToken}`,
},
}
);
const activity = graphResponse.data.signInActivity;
alert(
"Last Sign-In: " + (activity?.lastSignInDateTime || "Not found")
);
} catch (error) {
console.error("Graph API Error", error);
}
};
return (
<div style={{ padding: 30 }}>
<h2>Azure AD Login App</h2>
{!isAuthenticated ? (
<button onClick={handleLogin}>Login</button>
) : (
<>
<p>Welcome, <strong>{accounts[0]?.username}</strong></p>
<button onClick={getSignInActivity}>Get Last Sign-In</button>
<button onClick={handleLogout} style={{ marginLeft: 10 }}>
Sign out / Switch Account
</button>
</>
)}
</div>
);
}
export default App;
User login:
When clicked on Get last sign-in got the response successfully: