Extending login session duration
# support
a
Hello! We are wondering how we can extend the login session duration for users. Our providers often spend over an hour in the portal for charting, and they're getting frustrated due to frequent (hourly) logouts. Is there a way for us to adjust this setting? We're not self-hosting the backend. Thanks in advance!
a
Yes... I agree 100%! I would be very interested to find out how to do this also. I wrote about the very same challenge around this in a recent post here: https://discord.com/channels/905144809105260605/1332907731962826834 ...but no solution yet! 😦
You might take a look at this, though... https://discord.com/channels/905144809105260605/1308564422096064604/1308564422096064604 And if you do check it out, and if it works... please let me know, so I can give it a go also. 🙂
r
Are you using the TS SDK on the client? Refresh functionality is baked into the client and may solve the logout issue. Here's some documentation of the Lifecycle Events https://www.medplum.com/docs/react/lifecycle-events As well as refreshIfExpired method https://www.medplum.com/docs/sdk/core.medplumclient.refreshifexpired
a
Thanks so much for these links, Reshma! And yes, I am using TypeScript SDK in my client. I will take a look at these lifecycle and refreshifexpired docs -- fingers crossed and thanks so much! 🙂
a
Hi @reshma, thank you for pointing me towards those useful resources 🙂 A few follow up questions regarding session management and token refreshing, if I may: - Does the
refreshIfExpired
method refresh the access token by using the refresh token (which lasts longer)? - How long does the refresh token last before it expires? - Does refreshing the access token once every few minutes to ensure the session stays active mean I'm keeping the user logged in for as long as the refresh token lasts? For context, here's the
useEffect
I'm using to do this in `src/App.tsx`:
Copy code
useEffect(() => {
  const refreshSession = async () => {
    if (medplum) {
      console.log('Session refreshed');
      await medplum.refreshIfExpired();
    }
  };
  const interval = setInterval(refreshSession, 5 * 60 * 1000);  // every 5 minutes
  return () => clearInterval(interval);
}, [medplum]);
r
> Does the refreshIfExpired method refresh the access token by using the refresh token (which lasts longer)? Yes that's right. It will grant a new access token, and roate the refresh token. Our The refresh tokens lasts 2 weeks by default
> Does refreshing the access token once every few minutes to ensure the session stays active mean I'm keeping the user logged in for as long as the refresh token lasts? Essentially you're kind of "daisy chaining" refresh tokens, so in theory refreshing every 5 minutes would keep you authenticated indefinitely I found this article pretty helpful for describing refresh tokens; https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/
a
Thank you, @rahul1
g
Hi @rahul1 , Thank you for providing the documentation! We are currently using a refresh token to extend user login sessions. Originally, the login token did not include a refresh token unless we explicitly specified the scope as 'openid offline_access'. Given this setup, do you think it would make sense or safe to track user activity (e.g., mouse movements or key stroke) and log them out if they remain inactive for a certain period?
/** * src/components/SessionManager.tsx * This component tracks user activity and logs out the user after 3 hours of inactivity. */ import { useEffect, useRef } from "react"; import { useMedplum } from "@medplum/react"; const INACTIVITY_TIMEOUT = 3 * 60 * 60 * 1000; // 3 hours export function SessionManager() { const medplum = useMedplum(); const timeoutId = useRef(null); useEffect(() => { const resetTimer = () => { if (timeoutId.current) { clearTimeout(timeoutId.current); } timeoutId.current = setTimeout(() => { console.log("User inactive for 3 hours, logging out..."); medplum.signOut(); }, INACTIVITY_TIMEOUT); }; window.addEventListener("mousemove", resetTimer); window.addEventListener("keydown", resetTimer); window.addEventListener("scroll", resetTimer); window.addEventListener("click", resetTimer); resetTimer(); return () => { if (timeoutId.current) { clearTimeout(timeoutId.current); } window.removeEventListener("mousemove", resetTimer); window.removeEventListener("keydown", resetTimer); window.removeEventListener("scroll", resetTimer); window.removeEventListener("click", resetTimer); }; }, [medplum]); return null; } In the main.tsx, we wraped the SessionMaager by MedplumProvider.
r
@Guoyi Z (Empallo) - there's also some updated documentation here https://www.medplum.com/docs/auth/token-lifetime
340 Views