-1

I have an authentication system, and I want to show different <Routes> with different available paths considering from login state.

I uesd <Navigate/> element for redirection from hidden pages depending login state. But there is a problem. <Navigate/> redirects without considering the state.

For example, when I logged in and try to open Login page I must redirects to a Main page, and when I don't logged in and try to open profile I must redirect to Login Page. And when I try to open any of this pages I automaticly redirects to Main page.

routes.jsx:

import React from 'react';
import {
    Routes,
    Route,
    Navigate
  } from 'react-router-dom';
import Profile from './pages/Profile/Main/Profile';
import Login from './pages/Auth/Login/Login';
import Register from './pages/Auth/Register/Register';
import Main from './pages/Main/Main';
import { Loans } from './pages/Profile/Active/Loans';
import ErrorPage from './pages/errorPage/ErrorPage';

export const useRoutes = isAuthenticated => {
    if(isAuthenticated){
        return (
            <Routes>
                <Route path='/profile' exact>
                    <Route index path=":id" element={<Profile/>}/>
                    <Route path="loans" element={<Loans/>} exact/>
                </Route>
                <Route path='/' exact element={<Main/>}/>
                <Route
                    path="*"
                    element={<ErrorPage/>}
                />
                <Route
                    path="/auth/*"
                    element={<Navigate to="/" replace />}
                />
            </Routes>
        );
    } else {
        return (
            <Routes>
                <Route path='/auth' exact>
                    <Route path='login' element={<Login/>} exact />
                    <Route path="register" exact element={<Register/>}/>
                    <Route
                        path=""
                        element = {
                            <Navigate to="login" replace />
                        }
                    />
                </Route>
                <Route path='/' exact element={<Main/>}/>
                <Route
                        path="/profile/*"
                        element={<Navigate to="/auth/login" replace />}
                    />
                <Route
                    path="*"
                    element={<ErrorPage/>}
                />
            </Routes>
            )
    }
    
}

App.jsx:

import {
  BrowserRouter
} from 'react-router-dom';
import {useRoutes} from './routes';
import 'materialize-css';
import { useAuth } from './hooks/auth.hook';
import { AuthContext } from './context/auth.context';


function App() {
  const {token, userId, login, logout} = useAuth();
  const isAuthenticated = !!token;
  const routes = useRoutes(isAuthenticated);
  return (
    <AuthContext.Provider value = {{
        token, login, logout, userId, isAuthenticated
      }}>
      <BrowserRouter>
        <div className="container">
          {routes}
        </div>
      </BrowserRouter>
    </AuthContext.Provider>
  );
}

export default App;
Remon
  • 1
  • 1
  • Please include all the relevant code you are working with. There is no `Navigate` component in the shared code snippet. https://stackoverflow.com/help/minimal-reproducible-example Also, see if this [answer](https://stackoverflow.com/a/66289280/8690857) helps clear up how to create and use route protection. – Drew Reese Jun 10 '22 at 18:09
  • Your issue is with some redirection depending on state using Navigate, so you must share the part of the code where you are using Navigate, the part that is causing the issue – Osmanys Fuentes-Lombá Jun 10 '22 at 18:18
  • I add a part of code with the ```Navigate``` component – Remon Jun 10 '22 at 18:35
  • Did you get a chance to look over the other answer I linked regarding setting up route protection? – Drew Reese Jun 10 '22 at 20:54

1 Answers1

0

One issue that may be causing this is you check authentication based on whether the token exists. Debug the output of that variable to see if it is cleared correctly when you log out. Next, you are determining authentication once inside of App(), fetching the routes from useRoutes(), and then rendering the app without ever checking again if the authentication is still valid. A better approach would be something like this:

 const auth = useAuth();
return ({auth.isAuthenticated ? (
      <Fragment>
        <Link to="/account">Account ({auth.user.email})</Link>
        <Button onClick={() => auth.signout()}>Signout</Button>
      </Fragment>
    ) : (
      <Link to="/signin">Signin</Link>
    )});
skr
  • 1,700
  • 1
  • 15
  • 39