HomeIsWhereThePcIs
HomeIsWhereThePcIs

Reputation: 1464

RTK Query running twice instead of once

This is an authorizaton middleware component that wraps the App component in a React app using Redux Toolkit. The authorization is done using an access_token cookie. There is a also a logged_in cookie with httponly=false so the client knows its logged in, and a refresh_token cookie.

The logic is:

I do not like this state machine approach, but I have tried everything else and I kept getting strange loops, or queries not running at all.

export const AuthMiddleware: React.FC<{ children: React.ReactElement }> = 
    ({ children }) => {
  const [state, setState] = useState(1);
  const [cookie, , removeCookie] = useCookies(["logged_in"]);
  const hasLoggedInCookie = cookie.logged_in === "true";

  const { isSuccess: whoAmISuccess, isError: whoAmIError } = 
    useGetWhoAmIQuery(undefined, { skip: state !== 2 && state !== 4 });
  const { isSuccess: refreshSuccess, isError: refreshError } = 
    useRefreshTokenQuery(undefined, { skip: state !== 3 });

  if (state === 1) {
    setState(hasLoggedInCookie ? 2 : 0);
  }
  if (state === 2 && whoAmIError) setState(3);
  if (state === 2 && whoAmISuccess) setState(0);
  if (state === 4 && whoAmISuccess) setState(0);
  if (state === 4 && whoAmIError) {
    removeCookie("logged_in");
    setState(0);
  }
  if (state === 3 && refreshError) {
    removeCookie("logged_in");
    setState(0);
  }
  if (state === 3 && refreshSuccess) {
    setState(4);
  }

  console.log(state);
  if (state !== 0) {
    return <FullScreenLoader />;
  }
  return children;
};

As far as functionality goes this works, but there are two strange issues:

  1. When it gets to the point where the RefreshToken endpoint needs to be invoked, the endpoint is queried twice in a row. refresh endpoint queried twice
  2. If I log the state, it looks as the state goes backwards sometime, for example it goes 3-2-3 or 4-3-4, even though from the code it is not possible for the state to go from 4 to 3 or from 3 to 2.

There is obviously something I'm doing wrong here but after two days of banging my head against this problem I can't figure it out.

Upvotes: 1

Views: 3880

Answers (1)

phry
phry

Reputation: 44086

There is a refresh token approach in the documentation that lives in RTK Query, not in a component - have you tried that?

Automatic Reauthorization by extending fetchBaseQuery

Your code would come down to a single useGetWhoAmIQuery() call.

Also, something like a token refresh (if you choose this approach here) should always be a mutation, not a query. Then it could also invalidate the getWhoAmIQuery and it could automatically refetch - no need for you to orchestrate that!

Upvotes: 2

Related Questions