0

I've inherited a React App with the following structure, but it doesn't have an App.js so I am confused on how to implement the Login page to force a user to login before they can go to other pages or dashboard.

I'm guessing the login would set a state.user = { some user object } and somewhere it would check if the state user is null then go to the login page.

Let me know if you need to see other code snippets

react-app
  public
     index.html
  src 
     layouts
        Dashboard
           Dashboard.jsx
        Pages
           Pages.jsx
     routes
        dashboard.jsx
        index.jsx
        pages.jsx 
     views 
        Pages
           LoginPage.jsx 
     index.js

index.js

import React from "react";
import ReactDOM from "react-dom";
import { createBrowserHistory } from "history";
import { Router, Route, Switch } from "react-router-dom";
import indexRoutes from "routes/index.jsx";

const hist = createBrowserHistory();

ReactDOM.render(
  <Router history={hist}>
    <Switch>
      {indexRoutes.map((prop, key) => {
        return <Route path={prop.path} key={key} component={prop.component} />;
      })}
    </Switch>
  </Router>,
  document.getElementById("root")
);

routes/index.jsx

import Pages from "layouts/Pages/Pages.jsx";
import Dashboard from "layouts/Dashboard/Dashboard.jsx";

var indexRoutes = [
  { path: "/pages", name: "Pages", component: Pages },
  { path: "/", name: "Home", component: Dashboard }
];

export default indexRoutes;
sbolel
  • 3,312
  • 23
  • 42
David
  • 1,830
  • 1
  • 16
  • 19
  • What have you tried so far? I recommend reading [How to create a Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve), it is a helpful resource that may help you get better quality answers. – sbolel Jan 27 '19 at 00:10
  • Possible duplicate of [How to implement authenticated routes in React Router 4?](https://stackoverflow.com/questions/43164554/how-to-implement-authenticated-routes-in-react-router-4) – sbolel Jan 27 '19 at 00:17

2 Answers2

2

First of all you have to keep in mind that the React state is reset on a page refresh, meaning you will be "logged out" every time that happens. I would therefore recommend keeping the user credentials in localStorage instead.

React Router is very dynamic and you can have multiple Switch blocks. This is similar to how I usually solve it:

class Routes extends React.Component {
    render() {
        return (
            <Router>
                <Switch>
                    <Route path="/login" component={Login} />
                    <Route path="/"
                           render={props => {
                               if (this.isLoggedIn()) {
                                   return <LoggedInRoutes {...props} />;
                               } else {
                                   return <Redirect to="/login" />;
                               }
                           }} />
                </Switch>
            </Router>
        )
    }

    isLoggedIn() {
        return localStorage.getItem("user") != null;
    }
}

class LoggedInRoutes extends React.Component {
    render() {
        return (
            <Switch>
                <Route path="/pages" component={Pages} />
                <Route path="/" component={Dashboard} />
            </Switch>
        )
    }
}

You can then place all of your routes that don't require authentication in the Routes component, and all the other in the LoggedInRoutes component.

darksmurf
  • 3,029
  • 5
  • 20
  • 31
1

Added this to line 9 in index.js

import React from "react";
import ReactDOM from "react-dom";
import { createBrowserHistory } from "history";
import { Router, Route, Switch } from "react-router-dom";
import indexRoutes from "routes/index.jsx";

const hist = createBrowserHistory();

// TODO: store the bearer token and actually call a validateToken
//       function instead of checking if user is null but this is 
//       just for POC
if (localStorage.getItem("user") == null) { 
  hist.push("/pages/login-page"); 
}

ReactDOM.render(
  <Router history={hist}>
    <Switch>
      {indexRoutes.map((prop, key) => {
        return <Route path={prop.path} key={key} component={prop.component} />;
      })}
    </Switch>
  </Router>,
  document.getElementById("root")
);
David
  • 1,830
  • 1
  • 16
  • 19