admin管理员组

文章数量:1302328

I wanted to refresh the token every 1 hour ONLY if there is a user activity. Otherwise just remove the token.

Currently, my code below does call the refresh api every 1 hour regardless whether there is user activity or not.

User activity is any movement on your keyboard or mouse.

const App = () => {
  const refreshTokenInterval = () => {
    try {
      const isLoggedIn = useAuthStore.getState().isLoggedIn;
      if (isLoggedIn) {
        AuthenticationService.refresh(null, (response) =>
          CookieService.set(activeAccount, response.data)
        );
      }
    } catch (error) {
      console.log(error);
    } finally {
      setTimeout(refreshTokenInterval, 1000 * 60 * 60);
    }
  };

  useEffect(() => {
    refreshTokenInterval();
  }, []);

  return null;
};

export default App;

I wanted to refresh the token every 1 hour ONLY if there is a user activity. Otherwise just remove the token.

Currently, my code below does call the refresh api every 1 hour regardless whether there is user activity or not.

User activity is any movement on your keyboard or mouse.

const App = () => {
  const refreshTokenInterval = () => {
    try {
      const isLoggedIn = useAuthStore.getState().isLoggedIn;
      if (isLoggedIn) {
        AuthenticationService.refresh(null, (response) =>
          CookieService.set(activeAccount, response.data)
        );
      }
    } catch (error) {
      console.log(error);
    } finally {
      setTimeout(refreshTokenInterval, 1000 * 60 * 60);
    }
  };

  useEffect(() => {
    refreshTokenInterval();
  }, []);

  return null;
};

export default App;
Share Improve this question edited Apr 13, 2023 at 4:29 Joseph asked Apr 13, 2023 at 3:05 JosephJoseph 7,78531 gold badges104 silver badges228 bronze badges 1
  • 1 What's your definition of user activity. – Evert Commented Apr 13, 2023 at 3:34
Add a ment  | 

4 Answers 4

Reset to default 2

I've abstracted the logic into a hook. The basic logic is based on a running interval that calls the refreshTokenInterval handler once every hour (or any interval you need), and event listeners that detect if there was any activity at all during the previous interval's duration. If there was activity the the refreshTokenInterval pletes the token refresh logic, otherwise if there was no activity refreshTokenInterval kills the running interval and clears the activity event listeners.

Code:

const INTERVAL_TIME = 1000 * 60 * 60;

const events = [
  "mousedown",
  "mousemove",
  "wheel",
  "keydown",
  "touchstart",
  "scroll"
  // ... add other events here ...
];

const addListeners = (events, cb) => {
  events.forEach((event) =>
    window.addEventListener(event, cb, { passive: true })
  );

  return () => {
    events.forEach((event) =>
      window.removeEventListener(event, cb, { passive: true })
    );
  };
};

const useRefreshTokenInterval = (activeAccount, interval = INTERVAL_TIME) => {
  const intervalRef = React.useRef();
  const unlistenRef = React.useRef();
  const wasActiveRef = React.useRef(false);

  React.useEffect(() => {
    const refreshTokenInterval = (initial) => {
      if (!initial && !wasActiveRef.current) {
        // Inactive, clearing interval, not refreshing token
        CookieService.remove(activeAccount);
        clearInterval(intervalRef.current);
        if (unlistenRef.current) {
          unlistenRef.current();
        }
        return;
      }
      try {
        const isLoggedIn = useAuthStore.getState().isLoggedIn;
        if (isLoggedIn) {
          // Attempting token refresh
          AuthenticationService.refresh(null, (response) =>
            CookieService.set(activeAccount, response.data)
          );
        }
      } catch (error) {
        console.log(error);
      } finally {
        // Reset activity for next interval
        wasActiveRef.current = false;
      }
    };

    refreshTokenInterval(true); // <-- initial call

    // Setup token refresh interval
    intervalRef.current = setInterval(refreshTokenInterval, interval);

    // Add activity event listeners
    unlistenRef.current = addListeners(events, () => {
      // There was some activity
      wasActiveRef.current = true;
    });

    // Return cleanup function to clear any running interval timer
    // and unsubscribes event listeners
    return () => {
      clearInterval(intervalRef.current);
      if (unlistenRef.current) {
        unlistenRef.current();
      }
    };
  }, [activeAccount, interval]);
};

Usage:

useRefreshTokenInterval("account"); // <-- I've no idea what activeAccount is 

本文标签: javascriptHandle User Inactivity and Logout in ReactStack Overflow