I'm creating a React app and I'm trying to protect some routes behind password authorization.
My component to handle this is the following :
(ProtectedRoute.js)
export default function ProtectedRoute({ code, redirect_path = '/login' }) {
if (code === 401) return <Navigate to={redirect_path} replace/>;
return <Outlet/>;
}
All I need to do is pass the HTTP status code returned by my back-end and if it corresponds to an unauthorized response then it asks the user to log in, otherwise they are allowed through.
I query my back-end from App.js in the following way :
(App.js)
export default function App() {
let [status, setStatus] = useState(401);
useEffect(() => {
fetch(
'http://localhost:5000/auth',
{
method: 'GET',
mode: 'cors',
headers: {
'id_token': sessionStorage.getItem('id_token')
}
}
)
.then(response => response.status)
.then(status => setStatus(status));
}, []);
console.log('status=' + status);
return (
<div className="App">
<Navbar is_logged_in={status === 200}/>
<ToastContainer/>
<Routes>
<Route index element={<Home/>}/>
<Route path="/vehicle/:id" element={<EV/>}/>
<Route element={<ProtectedRoute code={status}/>}>
<Route path="/add" element={<AddEV/>}/>
</Route>
<Route path="/filter" element={<Home/>}/>
<Route path="/compare" element={<Home/>}/>
<Route path="/login" element={<LoginRegister type="login"/>}/>
<Route path="/register" element={<LoginRegister type="register"/>}/>
<Route path="/logout" element={<Logout/>}/>
<Route path="*" element={<p>Nothing here: 404!</p>}/>
</Routes>
</div>
);
}
This works, except for one problem. When the user is sent to the login page and successfully authenticates, they are then sent back to the index. At this point, I would expect the code inside the useEffect hook to fire and update the value of status.
Instead nothing happens. If I manually refresh the page then the code is triggered and everything happens the way I'd expect it to.
Clearly the idea is correct but the implementation is wrong. Is what I want to achieve possible ? If so how should I go about it ?
Thanking you in advance for your suggestions.
useEffecthas an empty dependency, so it runs only once when theAppcomponent mounts. This is why it "works" when you reload the page. It reloads the app, i.e. remountsAppcomponent and theuseEffecthook callback is invoked. When exactly, and how often, do you want this"/auth"API to be called? On every access to a protected route? Or just when logging in/out to set thestatusstate?/URL. If that is not possible then whenever logging in/out should be enough.