1

I've been struggling for a few hours now trying to make my login route dynamic, where users who log in from the landing page get redirected back to the landing page after, and if you attempt to access a private route as a guest then you redirect to login, then continue to the original destination.

Now, a logged in user can access the private route just fine. A guest from the landing page can click log in and get redirected to the landing page after. But I have tried everything to redirect the user to the original destination (a private route) after logging in, but to no avail. The page doesn't budge from /login after getting credentials. Here's what I have:

Relevant Code

app.jsx

function App() {
  const [token, setToken] = useState(
    localStorage.getItem("token") ? localStorage.getItem("token") : ""
  );

 ...

  return (
    <div className="App">
      <BrowserRouter>
        <ScrollToTop />
        <Routes>
          <Route
            path="/login"
            element={
              <>
                <NavComponent_Sign />
                <SignIn handleToken={handleToken} />
              </>
            }
          />
          <Route element={<RequiredAuth />}>
            <Route
              path="/make%20a%20tag"
              element={
                <>
                  <NavComponentWrapper
                    token={token}
                    handleLogOut={handleLogOut}
                  />
                  <CreateTag />
                </>
              }
            />
          </Route>
      </BrowserRouter>
    </div>
  );
}

For <RequiredAuth />:

const RequireAuth = () => {
  const location = useLocation();
  const isAuth = localStorage.getItem("token") ? true : false;
  return isAuth ? (
    <Outlet />
  ) : (
    <Navigate to="/login" replace state={{ from: location }} />
  );
};

And finally, signin.jsx:

const handleRedirect = () => {
    if (location.state?.from) {
      navigate(location.state.from.pathname);
    } else {
      navigate("/");
    }
  };

function handleClick() {
    axios
      .post("http://127.0.0.1:8000/api/token/login", {
        password: password,
        username: username,
      })
      .catch(function (error) {
        if (error.response) {
          console.log(error.response);
          setErrors(true);
        }
      })
      .then(
        (response) => props.handleToken(response.data["auth_token"]),
        console.log(location.state.from.pathname),
        handleRedirect()
      );
  }

Expected result vs actual

With handleRedirect, I should be redirecting to the pathname, which I checked with console exists, but the page is stuck on /login. I noticed that if I replace handleRedirect with just navigate("/"), or any public route, it just works.

What I tried

  1. Tried to refactor into two .then() blocks, didn't work.
  2. Tried switching to a private wrapper component, instead of the current <Route element={<RequiredAuth />}> method. Worked less than the current set up.
  3. Contemplated binning the project, decided against it

I don't know what to do at this point, feels like I gave it my all with trying to make it work unless theres some outside factor I'm not considering. Does anyone have any ideas?

  • It looks like you have just about all the correct pieces to redirect back to the original route being accessed, but if you are still having struggle then please update your question to include all relevant code. Share the entire `SignIn` component so we can see what/where `location.state?.from` comes from. If you still need further help from there then try to create a *running* codesandbox demo that reproduces your issue that we can inspect and debug live. – Drew Reese Mar 14 '22 at 00:18

0 Answers0