how i can Make my dashboard protected component (Only registered user have access).And how dashboard navigation work

Viewed 286

I am developing a react app in which i need a user dashboard where user can view his tweets.and other tasks.

Steps which i have completed so far.

  1. authentication of users using rest api(node js,mongodb) is done.
  2. Login/sign up is completed
  3. Storing jwt token in browser storage.

My app components/pages are.

  1. Home(can be accessible by all users)
  2. About us(public can be access by all users)
  3. Dashboard(protected only accessible by registered user)
  4. Dashboard nested components like profile,search tweet etc.(protected )

Problems that i am facing.

  1. how jwt will use to access only my protected pages and also public pages
  2. how i make my dashboard navigation (nested navigation) .
3 Answers

You can create a withAuth component:

import { useRouter } from 'next/router';
import { useSelector } from 'react-redux';

const withAuth = (WrappedComponent) => {
  return (props) => {
    if (typeof window !== 'undefined') {
      const router = useRouter();

      const accessToken = localStorage.getItem('accessToken');

      if (!accessToken) {
        router.replace('/login');
        return null;
      }

      return <WrappedComponent {...props} />;
    }
    return null;
  };
};

export default withAuth;

And when you want to "protect" a page or component you can wrap the export with the withAuth component like this:

import withAuth from '../withAuth'

const Component = () => {
 return (
   <div></div>
 )
}

export default withAuth(Component)

You can create a custom route component like this example,

PrivateRoute.js

function PrivateRoute({ component: Component, ...rest }) {
  return (
    <>
      <Switch>
        <Route
          {...rest}
          render={(props) =>
            localStorage.getItem("userToken")
             ? <Component {...props} /> : <Redirect to="/Login" />
          }
        />
      </Switch>
    </>
  );
}

export default PrivateRoute;

and use this component as

<PrivateRoute component={Dashboard} path="/Dashboard" exact />

The PrivateRoute.js will check if user is there in localstorage. If user is not present, it will redirect to /Login

Publicroute.js

function PublicRoute({ component: Component, ...rest }) {
  return (
    <div>
      <Switch>
        <Route
          {...rest}
          render={(props) =>
            localStorage.getItem("userToken")? <Redirect to="/Dashboard" /> : <Component {...props} /> 
          }
        />
      </Switch>
    </div>
  );
}

and use this component as

<PublicRoute component={Login} path="/Login" />

when you hits /Login and if user is already logged in, PublicRoute.js will take you to your component, else will redirect to /Login page.

This does the trick

localStorage.getItem("userToken")? <Redirect to="/Dashboard" /> : <Component {...props} />

You can protect your routes by wrapping the route in a HOC and this HOC will have your auth verification logic baked into it. Here's How:

we have 2 routes

  1. Home screen (public)
  2. Dashboard (private)

Your router would look like: (Keeping it minimal)

        <Switch>
          <PrivateRoute path="/dash">
            <Dashboard />
          </PrivateRoute>
          <Route path="/">
            <Home />
          </Route>
        </Switch>

Here, PrivateRoute is an HOC Which takes a screen, and based on auth logic, either renders the screen or redirects user to desired location / shows UI.

export const PrivateRoute = ({children, ...props}) => {
   const auth = checkForTheToken();
   if(auth) return children
   return <Redirect to="/login" />
}
Related