soofstad / react-oauth2-pkce

Provider agnostic OAuth2 Authorization Code flow with PKCE for React
MIT License
125 stars 53 forks source link

Bug: New Access token isn't used after refresh token #190

Closed NiallWalshRAM closed 4 weeks ago

NiallWalshRAM commented 1 month ago

My application polls my backend every X minutes using the bearer token. If I leave it sit and poll and the access_token naturally expires. Subsequent calls continue to use the expired token rather than use the new access_token that is retrieved using the refresh_token

I can see the refresh token is used to get access_token I can see the local storage is updated correctly with the new access_token If I interact with my application and click to a new tab, new button press etc etc, it will use the new access_token It just seems to happen when the application polls freely with no user interaction.

const auth: IAuthContext = useContext(AuthContext);
  const { iUser } = useContext(ImpersonationContext);

  const apiGatewayFetch = async (
    endpoint: string,
    method: string,
    body?: string
  ) => {
    return await fetch(`${apiUrl}${endpoint}`, {
      method: method,
      headers: buildHeaders(body !== undefined),
      body: body,
    });
  };

  const buildHeaders = (bodyPresent: boolean) => {
    const headers = new Headers({
      Authorization: "Bearer " + auth.token,
    });

    if (bodyPresent) {
      headers.append("Content-Type", "application/json");
    }

    return headers;
  };

Screenshot 2024-10-10 at 11 16 40

ReactDOM.render(
  <React.StrictMode>
    <AuthProvider authConfig={authConfig}>
      <ThemeProvider theme={theme}>
        <App />
      </ThemeProvider>
    </AuthProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

Steps To Reproduce

  1. Setup a backend call to be polled.
  2. Allow access_token to expire, refresh token will get new access_token
  3. Any subsequent calls that are polled use the oldest token :(

The current behavior

My expectation that after the access_token is refreshed, the AuthContext token will use the newest access_token if backend calls are polled.

The expected behavior

What currently happens is that after the access_token is refreshed, the AuthContext token uses the oldest access_token if backend calls are polled.

soofstad commented 1 month ago

Hi @NiallWalshRAM I believe what is happening that the "setInterval" or similar you are using to regularly fetch "accounts" are not properly setup to reuse the new token value. For example this code that replaces the "interval" function when any dependent variables update.

  useEffect(() => {
    const interval = setInterval(() => doAPICallRegulary(token))
    return () => clearInterval(interval)
  }, [token]) 

Could you please provide a full example of all involved functions and classes?

NiallWalshRAM commented 4 weeks ago

Hi @soofstad,

Thank you for the added information above. After your feedback, I updated one of my setIntervals calls to updated everytime the token updates like above and I can confirm this resolves the issue I'm facing.

Really appreciate the time you've spent to help me on this.

BR, Niall