代码之家  ›  专栏  ›  技术社区  ›  Darsh. S.

一旦用户从react中的私有路由中注销,我如何防止react组件的可访问性?

  •  1
  • Darsh. S.  · 技术社区  · 11 月前

    我一直在制作非常简单的反应页面,只是为了清楚我的概念。在这里,我有一个简单的身份验证方法,将登录信息存储在 users.json 文件(这只是为了简化程序)。

    这是简单明了的代码 AuthProvider.jsx

    import { createContext, useContext, useState } from "react";
    import { useNavigate } from "react-router-dom";
    import users from "../json/users.json";
    const AuthContext = createContext();
    
    const AuthProvider = ({ children }) => {
        const navigate = useNavigate();
        const [user, setUser] = useState(null);
    
        const login = (email, password) => {
            const foundUser = users.find(
                (u) => u.email === email && u.password === password
            );
    
            if (foundUser) {
                console.log("creds match");
                setUser(foundUser.email);
                navigate("/dashboard");
                return true;
            } else {
                console.log("creds do not match");
                return false;
            }
        };
    
        const logout = () => {
            setUser(null);
            navigate("/login");
        };
    
        return (
            <AuthContext.Provider value={{ user, login, logout }}>
                {children}
            </AuthContext.Provider>
        );
    };
    
    export const useAuth = () => {
        return useContext(AuthContext);
    };
    
    export default AuthProvider;
    

    我在我的账户中添加了一条私人路线 App.jsx 以便只有经过身份验证的用户才能访问仪表板组件。以下是代码 PrivateRoute.jsx

    import { Outlet } from "react-router-dom";
    import { Navigate } from "react-router-dom";
    import { useAuth } from "./AuthProvider"
    
    const PrivateRoute = () => {
        const user = useAuth();
        if (!user) return <Navigate to="/login" />
        return <Outlet />
    }
    
    export default PrivateRoute;
    

    问题在于注销操作之后。一旦我注销,并点击窗口中的上一页按钮,我就会被重定向到仪表板,这在我注销后是不应该发生的。或者,如果我尝试直接输入 "/dashboard" 通过URL中的路由,我再次被重定向到仪表板。

    据我所知, PrivateRoute 应该能防止这种事情发生。有人能解释为什么会发生这种情况吗?此外,我知道我可以简单地使用条件呈现来检查是否有用户,并相应地呈现相应的组件。但是 私人路线 正在做同样的事情。那么,这背后的原因是什么?

    这是我的代码 附录jsx 组件。它包含了所有的路线。

    import { Routes, Route } from "react-router-dom";
    import { BrowserRouter } from "react-router-dom";
    import Login from "./components/Login";
    import Dashboard from "./components/Dashboard";
    import AuthProvider from "./hooks/AuthProvider";
    import Navbar from "./components/Navbar";
    import Signup from "./components/Signup";
    import Home from "./components/Home";
    import PrivateRoute from "./hooks/PrivateRoute";
    
    export default function App() {
      return (
        <div className="App">
          <BrowserRouter>
            <AuthProvider>
              <Navbar />
              <Routes>
                <Route path="/" element={<Home />} />
                <Route path="/login" element={<Login />} />
                <Route path="/signup" element={<Signup />} />
                <Route element={<PrivateRoute />} >
                  <Route path="/dashboard" element={<Dashboard />} />
                </Route>
              </Routes>
            </AuthProvider>
          </BrowserRouter>
        </div>
      );
    }
    

    这是唯一相关的代码。其余组件仅包括主页、仪表板、登录注册。

    1 回复  |  直到 11 月前
        1
  •  1
  •   Drew Reese    11 月前

    问题是 const user = useAuth(); 在里面 PrivateRoute 在这里 user 整个的 auth上下文值,因此作为truthy对象 Outlet 正在渲染,而不是 Navigate 组件将用户跳转到您的身份验证路由。

    你应该 破坏 这个 用户 提供的身份验证上下文中的值:

    const { user } = useAuth();
    

    完整代码:

    const PrivateRoute = () => {
      const { user } = useAuth();
    
      return user ? <Outlet /> : <Navigate to="/login" />;
    };