Reputation: 1797
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.
Upvotes: 0
Views: 751
Reputation: 15462
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>
);
};
Upvotes: 1