首页 > 解决方案 > 如何添加身份验证以响应路由器

问题描述

这就是我所拥有的:

//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")
);

如您所见,您可以同时访问“admin”和“auth”下的所有页面,而无需进行任何身份验证检查。文件夹“layouts/”下的文件都有:

import routes from "routes.js";

和(布局数据的一部分)分别:

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

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

router.js 包含以下内容:

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;

要添加身份验证,我遵循了本指南:

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

所以我在 index.js 中添加了这个:

export const fakeAuth = {
    signedIn: false
};

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

        return children;
};

然而,发生了什么,无论我去什么网址,我都会被重定向到这个:

http://localhost:3003/auth/login

问题是页面完全是空的,控制台中没有错误。由于某种原因未呈现登录页面。它看起来不像我进入一个无限循环。

标签: reactjs

解决方案


问题是:

export const fakeAuth = {
  signedIn: false,
};

正如变量名称所示,这只是模拟身份验证。fakeAuth永远不会更改您的代码,因此:

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

将始终评估为true. 这意味着您将始终停留在登录页面上。


因此,您需要创建一种能够跟踪和更新身份验证/授权状态的机制。

就身份验证和授权而言,有很多方法可以解决。我会设置一个后端应用程序,您的 React 应用程序可以向它发送请求,以授权/验证用户。

但是,您决定处理实际的身份验证/授权,您可能还希望使用诸如localStorage在刷新期间保持登录状态之类的东西。

为此,您可以创建自定义钩子,如下所示:

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 };
};

然后你可以像这样使用它:

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

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

  return children;
};

和这个:

// 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>
  );
};

推荐阅读