reactjs React中使用firebase的受保护路由

t5fffqht  于 2022-12-22  发布在  React
关注(0)|答案(1)|浏览(118)

''我正在使用firebase认证来登录用户,然后将角色信息存储在真实的数据库中。如果一个具有管理员角色的用户登录到站点,那么他们应该能够访问“/home”路由,但我不能这样做。
App.js

import "./App.css";

import React from "react";
import { Route, Routes, Navigate } from "react-router-dom";

import Landing from "./components/Landing";
import PhoneDetails from "./components/PhoneDetails";
import Home from "./components/Home/App.jsx";
import Signup from "./components/Signup";
import SignIn from "./components/Signin";
import ForgotPassword from "./components/ForgotPassword";

import { auth } from "./firebase-config.js";
import { useEffect } from "react";
import FirebaseData from "./firebaseData";

function App() {
  document.body.style = "background: #F8F5FA;";

  // getting the user data from firebase
  const firebaseData = FirebaseData();

  const [displayName, setDisplayName] = React.useState("");
  const [isAuthenticated, setIsAuthenticated] = React.useState(false);
  const [role, setRole] = React.useState("");

  useEffect(() => {
    if (firebaseData) {
      auth.onAuthStateChanged((user) => {
        if (user) {
          // User is signed in
          // ...
          setIsAuthenticated(true);
          setDisplayName(user.displayName);
          setRole(firebaseData.users?.[user.uid]?.role);
        } else {
          // User is signed out
          // ...
          setIsAuthenticated(false);
          setDisplayName("");
          setRole("");
        }
      });
    }
  }, [firebaseData]);

  console.log("isAuthenticated:", isAuthenticated);
  console.log("displayName:", displayName);
  console.log("role:", role);

  return (
    <Routes>
      <Route
        path="/"
        exact
        element={
          <Home
            isAuthenticated={isAuthenticated}
            displayName={displayName}
            role={role}
          />
        }
      />
      <Route path="/signup" element={<Signup />} />
      <Route path="/signin" element={<SignIn />} />
      <Route path="/forgot-password" element={<ForgotPassword />} />

      <Route
        path="/home"
        element={
          isAuthenticated && role === "admin" ? (
            <Landing />
          ) : (
            <Navigate replace to="/" />
          )
        }
      />

      <Route
        path="/details"
        element={
          isAuthenticated && role === "admin" ? (
            <PhoneDetails />
          ) : (
            <Navigate replace to="/" />
          )
        }
      />
      <Route path="/" element={<Navigate replace to="/" />} />
    </Routes>
  );
}

export default App;

下面给出的是我正在获取的真实的数据文件
firebaseData.js

import {database} from "./firebase-config";
import React from "react";
import {ref, onValue} from "firebase/database";
import {useEffect} from "react";

const db = database;

export default function FirebaseData() {
    const [data, setData] = React.useState(null);

    useEffect(() => {
        onValue(ref(db), (snapshot) => {
            setData(snapshot.val());
        });
    }, []);
    return data;

}

我正在检查身份验证状态,并在控制台日志中获取角色,但当我路由到/home时,我被重定向到/ route。我知道由于useEffect挂钩,我无法立即从DB获取数据,如何解决此问题?

iqxoj9l9

iqxoj9l91#

假设用户为admin时,role =“admin”,则可以这样做

<Routes>
  <Route
    path="/"
    exact
    element={
      <Home
        isAuthenticated={isAuthenticated}
        displayName={displayName}
        role={role}
      />
    }
  />
  <Route path="/signup" element={<Signup />} />
  <Route path="/signin" element={<SignIn />} />
  <Route path="/forgot-password" element={<ForgotPassword />} />
    {
     role==='admin' && <Route
    path="/home"
    element={
      isAuthenticated && role === "admin" ? (
        <Landing />
      ) : (
        <Navigate replace to="/" />
      )
    }
  />
 }
  
  <Route
    path="/details"
    element={
      isAuthenticated && role === "admin" ? (
        <PhoneDetails />
      ) : (
        <Navigate replace to="/" />
      )
    }
  />
  <Route path="/" element={<Navigate replace to="/" />} />
</Routes>

对于管理员以外的角色,将使用默认路由。

相关问题