Skip to content
Advertisement

React router v6: Protected Routes displaying after logging out

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;
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement