Redirect when the user is not logged in

Viewed 595

I have the following routes in App.js

<Router>
  <div className="App">
    <Layout>
      <Route exact path="/" exact component={Main} />
      <Route exact path="/passwordchange/:email" component={PasswordChange} />
      <Route exact path="/account" component={Account} />
      <Route exact path="/forgot-password" component={ForgotPassword} />
      <Route exact path="/login" component={Login} />
      <Route exact path="/faq" component={FAQ} />
      <Route exact path="/library" component={Library} />
      <Route exact path="/signup" component={SignUp} />
      <Route exact path="/signup/:id" component={SignUp} />
      <Route exact path="/login/:id" component={Login} />
      <Route path="/books" exact component={BookSummaries} />
      <Route path="/home" exact component={Main} />
      <Route path="/pricing" exact component={Pricing} />
      <Route path="/books/:id" exact component={BookDetail} />
      <Route path="/categories/:id" exact component={Categories} />
      <Route path="/category/:category" exact component={BookListPage} />
      <Route path="/stacksocial" exact component={StackSocial} />
      <Route path="/booklist/:sort" exact component={BookListPage} />
      <Route path="/reader/:id" exact component={Reader} />
      <Route path="/search" exact component={BookSearch} />
      <Route path="/payment/:planid" exact component={Payment} />
    </Layout>
  </div>
</Router>

For some of the routes, I want to only show them if the user is logged in. What's the best way to do that using React?

2 Answers

The best way to do it is by creating a ProtectedRoute component. If the user is not logged in, redirect them to somewhere else such as the login page.

Here is ProtectedRoute.js (here I have an authService to decide if the user is logged in or not; yours can be different).

import React from "react";
import { Route, Redirect } from "react-router-dom";
import authService from "../../services/auth-service";

export const ProtectedRoute = ({
  path,
  component: Component,
  render,
  ...rest
}) => {
  return (
    <Route
      path={path}
      {...rest}
      render={props => {
        if (authService.isAuthenticated()) {
          return Component ? <Component {...props} /> : render(props);
        } else {
          return <Redirect to="/login" />;
        }
      }}
    />
  );
};

export default ProtectedRoute;

This way you can use this component for the routes that require authentication.

<Router>
  <div className="App">
    <Layout>
      <Route exact path="/" exact component={Main} />
      <ProtectedRoute exact path="/passwordchange/:email" component={PasswordChange} />
    </Layout>
  </div>

Assuming you have some sort of isLoggedIn variable somewhere. You could do it with something like:

<Router>
                <div className="App">
                    <Layout>
                        <Route exact path="/" exact component={Main}/>
                        <Route exact path="/passwordchange/:email" component={PasswordChange}/>
                        <Route exact path="/account" component={Account}/>
                        <Route exact path="/forgot-password" component={ForgotPassword}/>
                        <Route exact path="/login" component={Login}/>
                        <Route exact path="/faq" component={FAQ}/>
                        <Route exact path="/library" component={Library}/>
                        <Route exact path="/signup" component={SignUp}/>
                        <Route exact path="/signup/:id" component={SignUp}/>
                        <Route exact path="/login/:id" component={Login}/>
                        <Route path="/books" exact component={BookSummaries}/>
                        { isLoggedIn &&
                        <>
                          <Route path="/home" exact component={Main}/>
                          <Route path="/pricing" exact component={Pricing}/>
                          <Route path="/books/:id" exact component={BookDetail}/>
                          <Route path="/categories/:id" exact component={Categories}/>
                          <Route path="/category/:category" exact component={BookListPage}/>
                          <Route path="/stacksocial" exact component={StackSocial}/>
                          <Route path="/booklist/:sort" exact component={BookListPage}/>
                          <Route path="/reader/:id" exact component={Reader}/>
                          <Route path="/search" exact component={BookSearch}/>
                          <Route path="/payment/:planid" exact component={Payment}/>
                        </>
                      }
                    </Layout>
                </div>
            </Router>
Related