Onjsdev

Share


Protected Routes With React Router v6


By onjsdev

Nov 8th, 2023

Protected routes are routes with a guard in front of the navigation routes to check whether the necessary conditions for visiting these routes are met. These conditions are mostly related to authentication and authorization, so we will show a page to the user depending on whether its isAuthenticated key in local storage has been assigned as true or false.

Let's start with configuration of react router v6

Add Routing To App With React Router V6

To add routing to your Reactjs app with react-router v6, the first thing you need to do is install the packages and wrap your App tag with the BrowserRouter tag imported from the react-router-dom package.

npm i react-router react-router-dom
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { BrowserRouter } from 'react-router-dom';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);

Setting Routes

We will have two routes. One of them is the login route for getting credentials. Other is the dashboard route, which will be protected. Realize that we have a parent element, AuthOnly, to protect the dashboard route.

import Auth from './views/Auth';
import AuthOnly from './views/AuthOnly';
import Dashboard from './views/Dashboard';
import { Route, Routes } from 'react-router';

function App() {
  return (
    <Routes>
      <Route path='/auth/login' element={<Auth />}></Route>
      <Route
        path='/dashboard'
        element={
          <AuthOnly>
            <Dashboard />
          </AuthOnly>
        }
      ></Route>
    </Routes>
  );
}

export default App;

Create Wrapper Component, AuthOnly, To Protect Dashboard Route

This is the main part of the article, let's explain what the following code snippet do. The following component is a parent component. When created, the user's authorization status is checked and if the user is authenticated, the dashboard component will be rendered with the help of the children prop, otherwise the user will be redirected to the login route.

import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router';

function AuthOnly({ children }) {
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const navigate = useNavigate();
  useEffect(() => {
    /* Send credentials to the server to check if user is authenticated */

    if (localStorage.getItem('isAuthenticated')) {
      setIsAuthenticated(true);
    } else {
      navigate('/auth/login');
    }
  }, []);
  // if (isAuthenticated == true -> children) else -> null 
  return isAuthenticated && children;
}

export default AuthOnly

Create Page Component For Login Route

In this step, we will create other element component, Auth, to simulate the authentication process. This component will render a form. When a user submits the form, we will simply set isAuthenticated as true in localStorage and accept the user as authenticated and also redirect the user dashboard page.

import React from "react";
import { useNavigate } from "react-router";

function Auth() {
  const navigate = useNavigate();

  function handleClick(e) {
    e.preventDefault();
    localStorage.setItem("isAuthenticated", true);
    // Redirect the user dashboard
    navigate("/dashboard");
  }

  return (
    <form>
      <input placeholder="email" />
      <input type="password" placeholder="password" />
      <input onClick={handleClick} type="submit" value="Login" />
    </form>
  );
}

export default Auth;

Create Page Component For Dashboard Route

The dashboard component is only navigated by authenticated users since it is displayed private data, which means it is protected, for the sake of simplicity, on our dashboard page, we will show a simple text and a logout button.

import React from 'react';
import { useNavigate } from 'react-router';

function Dashboard() {

  const navigate = useNavigate();

  function handleClick() {
    localStorage.removeItem('isAuthenticated');
    // Send the user login page
    navigate('/auth/login');
  }

  return (
    <div>
      Here is dashboard
      <button onClick={handleClick}>Logout</button>
    </div>
  );
}

export default Dashboard;

Conclusion

That's all, in this guide we have covered a way to protect a route in react js application with react router v6. Now, you can try to visit the dashboard route and go to the /auth/login route to test your implementation.

Thank you for reading.