TanStackT
TanStack2y ago
9 replies
verbal-lime

Best way to handle authenticated routes with http-only cookie

I am currently trying to find a way to process a http-only session cookie with Tanstack Router.

The docs explain that you can use the beforeLoad-fn to redirect to the login route if necessary.

My routes are

/login
/app (here starts the auth-area)
/app/vouchers
/app/...

export const Route = new FileRoute("/app").createRoute({
  beforeLoad: async ({ context: { queryClient } }) => {
    try {
      const user = await queryClient.ensureQueryData(currentUserQueryOptions());
      return { user };
    } catch (error) {
      console.log(error);
    }
  },
  component: App,
});

However, as an http-only cookie cannot be read on the client side, this option is difficult to implement. Therefore I have a zustand-store, which keeps the isLoggedIn-prop. In case of an 401 error the prop is set to false.
export const queryClient = new QueryClient({
  //....
  queryCache: new QueryCache({
    onError: (error) => {
      if (error?.response?.status === 401) {
        getToggleIsLoggedInAction()(false);
      }
    },
  }),
});

So far, I haven't come up with anything other than handling this prop in the app component with the help of useEffect
function App() {//component of Route /app
  const isLoggedIn = useIsLoggedIn();
  const { logout } = useLoginActions();
  const location = useRouterState({ select: (s) => s.location });
  const user = Route.useRouteContext({
    select: (s) => s.user,
  });
  const navigate = Route.useNavigate();

  useEffect(() => {
    if (!isLoggedIn && !location.href.includes("login")) {//feels a bit odd
      navigate({
        to: "/login",
        search: { redirect: location.href },
      });
    }
  }, [isLoggedIn, navigate, location.href]);

  const logoutUser = () => {
    logout({ app: "vouchers" });
  };

  return (
    <div>
      <NavBar user={user} onLogout={logoutUser} />
      <div>
        <Outlet />
      </div>
    </div>
  );
}

I would be very happy to receive feedback on how you would solve this.
Thx!
Was this page helpful?