Home > Net >  Running a "refresh token" function from reactjs every X minutes
Running a "refresh token" function from reactjs every X minutes

Time:11-13

I'm trying to refresh the authentication token every few minutes using a refresh token. My problem is that the token is saved in a Context (using useContext to retrieve it when necessary) and I'm struggling to use a setInterval-like function to read the current token, POST it to the server and renew it in the state.

This is what I'm trying to do:

  const {
    tryLocalSignIn,
    signin,
    signout,
    state: AuthState,
  } = useContext(AuthContext);

...

let id = setInterval(async () => {
  let token = AuthState.token;
  let refreshToken = AuthState.refreshToken;
  console.log("Running refresh token", token, refreshToken);
  let answer = await ApiRefreshToken(token, refreshToken);
  if (answer.status !== 200) {
    setError("Error using refresh token");
    return;
  }
  signin({
    token: answer.data.token,
    refreshToken: answer.data.refreshToken,
    expires_in: answer.data.expires_in,
  });
}, 15000);

...

But I'm unable to read from the AuthState

CodePudding user response:

Not sure from the code you provided how it's structured, but did you try passing AuthState into the setInterval callback function? As in

let id = setInterval(async (state) => {...}, 15000);

and then you access token by state.token or something?

CodePudding user response:

looks like most likely setInterval is refering to the stale state, if the setInterval in inside useEffect then you might need useRef to get access to the latest version of the varaible

 const SomeComponent = (props) => {
 
    const {
     tryLocalSignIn,
     signin,
     signout,
     state: AuthState,
    } = useContext(AuthContext);

     const AuthStateRef = useRef(AuthState)
     AuthStateRef.current = AuthState;
  
    .....
 
    useEffect(() =>  {

        let id = setInterval(async () => {
        let token = AuthStateRef.current.token;
        let refreshToken = AuthStateRef.current.refreshToken;
        console.log("Running refresh token", token, refreshToken);
         let answer = await ApiRefreshToken(token, refreshToken);
          if (answer.status !== 200) {
          setError("Error using refresh token");
           return;
          }
          signin({
           token: answer.data.token,
           refreshToken: answer.data.refreshToken,
           expires_in: answer.data.expires_in,
          });
         }, 15000);

         return () => {
            clearInterval(id)
         }

    }, [])  // check dependencies like, signin or AuthState
   

 } 

if you dont want the effect to run dependencices, then use useRef to get current references

  • Related