0

This is what I have:

//index.js
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Route, Switch, Redirect } from "react-router-dom";
import AdminLayout from "layouts/Admin.js";
import AuthLayout from "layouts/Auth.js";

ReactDOM.render(
  <BrowserRouter>
    <Switch>
        <Route path="/admin" render={(props) => <AdminLayout {...props} />} />
        <Route path="/auth" render={(props) => <AuthLayout {...props} />} />
        <Redirect from="/" to="/admin/index" />
    </Switch>
  </BrowserRouter>,
  document.getElementById("root")
);

As you can see, you can go both to all the pages under "admin" and "auth" without any auth check. The files under the folder "layouts/" have both an:

import routes from "routes.js";

And (a part from layout data) respectively:

<Switch>
  {getRoutes(routes)}
  <Redirect from="*" to="/admin/index" />
</Switch>

and

<Switch>
  {getRoutes(routes)}
  <Redirect from="*" to="/auth/login" />
</Switch>    

The router.js contains this:

import Index from "views/Index.js";
import Login from "views/examples/Login.js";
import Tables from "views/examples/Tables.js";

const routes = [
  {
    path: "/index",
    name: "Dashboard",
    icon: "ni ni-tv-2 text-primary",
    component: Index,
    layout: "/admin",
  },
  {
    path: "/tables",
    name: "Tables",
    icon: "ni ni-bullet-list-67 text-red",
    component: Tables,
    layout: "/admin",
  },
  {
    path: "/login",
    name: "Login",
    icon: "ni ni-key-25 text-info",
    component: Login,
    layout: "/auth",
  },
];
export default routes;

To add authentication I followed this guide:

https://www.nicknish.co/blog/react-router-authenticated-routes

So I added this in index.js:

export const fakeAuth = {
    signedIn: false
};

const RequireAuth = ({ children }) => {
        if (!fakeAuth.signedIn) {
            return <Redirect to="/auth/login" />;
        }

        return children;
};

However, what it happens it that, no matter what url I go to, I will always be redirected to this:

http://localhost:3003/auth/login

And the problem is that the page is completely empty with no errors in the console. The login-page is not rendered for some reason. And it does not look as I went inside an infinite loop.

1 Answer 1

1

The problem is:

export const fakeAuth = {
  signedIn: false,
};

As the name of the variable indicates, this is just mocking authentication. fakeAuth never changes in your code so this:

if (!fakeAuth.signedIn) {
  return <Redirect to="/auth/login" />;
}

will always evaluate to true. Meaning you will always stay on the login page.


So you need to create a mechanism that is able to track and update authentication / authorization status.

As far as authentication and authorization goes there are many ways to go about it. I would setup a backend application that your React app could send requests to, to authorize / authenticate users.

However you decide to handle the actual authentication / authorization you probably also want to use something like localStorage to persist login status across refreshes.

For this you could create custom a hook something like this:

export const useAuth = () => {
  const [isSignedIn, setIsSignedIn] = useState(
    localStorage.getItem("loggedIn") ? true : false
  );

  // For your actual application you will need to refactor this
  // based on your authentication / authorization implementation,
  // user input, etc...
  const handleLogin = () => {
    localStorage.setItem("loggedIn", true);
    setIsSignedIn(true);
  };

  return { isSignedIn, handleLogin };
};

Then you can use it like this:

// Other imports...
import { useAuth } from "./router";

const RequireAuth = ({ children }) => {
  const { isSignedIn } = useAuth();
  if (!isSignedIn) {
    return <Redirect to={LOGIN_URL} />;
  }

  return children;
};

and this:

// Other imports...
import { useAuth } from "./router";

const Login = () => {
  const { isSignedIn, handleLogin } = useAuth();
  if (isSignedIn) {
    return <Redirect to={DASHBOARD_URL} />;
  }

  return (
    <div>
      <p>Login to access Dashboard</p>
      <button onClick={() => handleLogin()}>Login</button>
    </div>
  );
};
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you but thats not really correct. The link I provided shows a working solution, even though there is a fakeLogin. My problem is that the page is completely blank, no matter if I use his or your solution.
Can you update your code so the problem is reproducible? Here's my forked sandbox based on the guide.
What I did was to download this bootstrap for react: creative-tim.com/product/argon-dashboard-react. And then just add the code you wrote above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.