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
- Tried to refactor into two
.then()
blocks, didn't work. - Tried switching to a private wrapper component, instead of the current
<Route element={<RequiredAuth />}>
method. Worked less than the current set up. - 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?