I am attempting to implement a private route in React; the homepage should not be visible until the user logs in. If I restart my frontend, all protected routes are not accessible until the user logs in. However, after the first login, all protected routes don’t seem to be protected; I can logout, the session is destroyed in my database and my backend sends a response of {isLoggedIn: false}, but for some reason I can still access the protected routes.
When I didn’t use ‘useState’, I could login and my backend would confirm I was logged in, but I still couldn’t access any protected routes. This is the closest I’ve got to my end goal, but obviously still doesn’t work. Any help would be appreciated.
Private Routes
import { useState, useEffect } from 'react'; import React from 'react'; import axios from 'axios'; const checkIfLogged = async () => { let[logged, setLogged] = useState(false); await axios.get("http://localhost:3001/auth", { withCredentials: true }).then((res) => { setLogged(res.data.isLoggedIn); }) return logged; } const updateAuth = async(check) => { const loggedIn = await check; return loggedIn; } const PrivateRoutes = () =>{ const loggedIn = updateAuth(checkIfLogged); return( loggedIn ? <Outlet /> : <Navigate to="/login" /> ) } export default PrivateRoutes;
Auth Check
app.get("/auth", (req, res) => { if(req.session.isAuth){ res.send({isLoggedIn: true}) } else{ res.send({isLoggedIn: false}) } })
App.js
import{ Routes, Route, } from "react-router-dom"; import React from "react"; import Home from "./screens/Home"; import About from "./screens/About"; import Login from "./screens/Login"; import Register from "./screens/Register"; import Logout from "./screens/Logout"; import PrivateRoutes from "./utils/private"; const App = () => { return ( <> <Routes> <Route element={<PrivateRoutes/>}> <Route path="/" exact element={<Home />}/> <Route path="/about" element={<About />}/> </Route> <Route path="/login" element={<Login />} /> <Route path="/register" element={<Register />}/> <Route path="/logout" element={<Logout />}/> </Routes> </> ); } export default App;
Advertisement
Answer
Another solution is by actually make a conditional rendering based on if the user is admin, then the page is rendered, otherwise a null
is returned:
so in your PrivateRoutes:
import { useState, useEffect } from 'react'; import React from 'react'; import axios from 'axios'; const PrivateRoute = async () => { let[logged, setLogged] = useState(false); let [isSuperUser,setIsSuperUser] = useState(false) // adding new state useEffect(()=>{ axios.get("http://localhost:3001/auth", { withCredentials: true }).then((res) => { setLogged(res.data.isLoggedIn); setIsSuperUser(res.data.isSuperUser) }) },[isLoggedIn]) return ( isLoggedIn&& isSuperUser?<Outlet/>:null ) } export default PrivateRoutes;