Token used before issued problem! (Time sync?!)

hey I have an architectural question, I am using auth0 in combination with my own API. Setup made after the official documentation how to setup react sdk.

So far so good. Now I want to have an onboarding to ask a user for some more info which is being send to my own backend. So my idea was inside my app I wrap my routes with a user provider which fetches the userinfo from my backend. I also extended the HOC with another withOnboarding HOC which uses the useUser context to decide if user has onboarded or not.

index.tsx

    ReactDOM.render(
      <React.StrictMode>
        <Auth0Provider {...providerConfig}>
          <BrowserRouter>
            <App />
          </BrowserRouter>
        </Auth0Provider>
      </React.StrictMode>,
      document.getElementById("root")
    );

app.tsx

export default function App() {
  const { isLoading, error, isAuthenticated } = useAuth0();

  if (error) {
    return <div>Oops... {error.message}</div>;
  }

  if (isLoading) {
    return <Loading />;
  }

  return (
    <Router>
      <ThemeProvider theme={theme}>
        <UserProvider>
          <CssBaseline />
          {isAuthenticated && <Navbar />}
          <Switch>
            <Route path="/login">
              <LoginPage />
            </Route>
            <ProtectedRoute path="/" exact component={HomePage} />
            <ProtectedRoute path="/profile" component={ProfilePage} />
          </Switch>
        </UserProvider>
      </ThemeProvider>
    </Router>
  );
}

ProtectedRoute.tsx

export const ProtectedRoute = ({
  component,
  ...args
}: React.PropsWithChildren<any>) => (
  <Route
    render={(props) => {
      let Component = withAuthenticationRequired(withOnboarding(component), {});
      return <Component {...props} />;
    }}
    {...args}
  />
);

withOnboarding.tsx

const withOnboarding = <P extends object>(
  Component: ComponentType<P>
): FC<P> => {
  return function WithOnboarding(props: P): JSX.Element {
    const history = useHistory();
    const isOnboarding = history.location.pathname === "/onboarding";
    const { isLoading, isOnboarded } = useUser();
    return isLoading ? (
      <LinearProgress />
    ) : !isOnboarded && !isOnboarding ? (
      <Redirect to="/onboarding" />
    ) : isOnboarded && isOnboarding ? (
      <Redirect to="/" />
    ) : (
      <Component {...props} />
    );
  };
};

userProvider.tsx

const UserProvider = (opts: UserProviderOptions): JSX.Element => {
  const { getAccessTokenSilently } = useAuth0();
  const { children } = opts;
  const [state, dispatch] = useReducer(reducer, initialUserState);
  useEffect(() => {
    (async (): Promise<void> => {
      const token = await getAccessTokenSilently();
      await http
        .authorized(token)
        .get("/rest/v1/users/me")
        .then((result) => {
          console.log(result);
          const user = result.data;
          dispatch({ type: "INITIALISED", user: user });
        })
        .catch(function (error) {
          dispatch({ type: "ERROR", error: loginError(error) });
        });
    })();
  }, [getAccessTokenSilently]);

 

  return (
    <UserContext.Provider
      value={{
        ...state,
        registerUser,
      }}
    >
      {children}
    </UserContext.Provider>
  );
};

All that usually works pretty well, but sometimes (especially when refreshing the page) I get an error about the token is missing or expired. My backend logs say “Token used before issued”! I was googleing it and found things like the time not being synced?!

I dont really know what to do, due to this issue is just occasionally happening… But I wanted to make sure, I handle auth0 and my backend in my project correctly… I was thinking that my user provider maybe tries to fetch the data too early, but when I log the token before the fetch its always present (but maybe wrong?!) On the other hand I kinda make sure in App.tsx that the userProvider will only load after auth0 has finished initialising and isLoading is false?! Anyone an idea?

1 Like

Hi @gutisAlex,

This could be a clock skew issue.

Take a look at this thread about a similar issue. You can use the leeway param to give some room for clock variance.

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.