受保护路由重定向到根路径的问题

问题描述 投票:0回答:1

我在 React 应用程序中遇到一个问题,登录后,刷新受保护的路由会将我重定向到根路径(“/”),但是当我刷新像 /myaccount 这样的非受保护的路由时,它不会重定向。

问题描述 登录后,如果我导航到 /dashboard 等受保护的路由并刷新页面,我将被重定向到“/”。 但是,当我位于 /myaccount 等不受保护的路由时,刷新页面不会重定向我。

期望的行为 我希望应用程序在刷新后保持当前状态,防止受保护和不受保护的路由重定向到根路径(“/”)。

我尝试过的 检查上下文中的令牌和 userType 状态管理。 确保 fetchData 函数在登录后正确检索用户类型。

代码 这是我的应用程序的相关代码: 应用程序.js

import React, { Suspense, lazy } from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Layout from "./components/layout/Layout";
import { CombinedProvider } from "./contexts/useContext";
import { ToastContainer } from "react-toastify";
import ProtectedRoute from "./utils/ProtectedRoute";

const SelectionPage = lazy(() => import("./pages/SelectionPage"));
const SignupPage = lazy(() => import("./pages/Signup"));
const LoginTanod = lazy(() => import("./pages/LoginTanod"));
const LoginResident = lazy(() => import("./pages/ResidentLogin"));

// Tanod routes
const Dashboard = lazy(() => import("./components/users/tanods/Dashboard"));
const Patrolmap = lazy(() => import("./components/users/tanods/Map"));
const Equipments = lazy(() => import("./components/users/tanods/Equipment"));
const Performance = lazy(() => import("./components/users/tanods/Performance"));
const Schedule = lazy(() => import("./components/users/tanods/Schedule"));
const Incidents = lazy(() => import("./components/users/tanods/Incidents"));
const MyAccount = lazy(() => import("./components/users/tanods/MyAcc"));

// Resident routes
const ResidentRating = lazy(() => import("./components/users/residents/TanodPersonels"));
const ResidentDashboard = lazy(() => import("./components/users/residents/Dashboard"));

function App() {
  return (
    <div className="flex-1 p-6 bg-background text-text">
      <BrowserRouter>
        <CombinedProvider>
          <Suspense fallback={<div>Loading...</div>}>
            <ToastContainer />
            <Routes>
              {/* Public Routes */}
              <Route path="/" element={<SelectionPage />} />
              <Route path="/tanod-login" element={<LoginTanod />} />
              <Route path="/resident-login" element={<LoginResident />} />
              <Route path="/signup" element={<SignupPage />} />
              <Route element={<Layout />}>
              <Route path="/myaccount" element={<MyAccount />}/>
              </Route>
              {/* Protected Routes for Tanod */}
              <Route element={<Layout />}>
                <Route
                  path="/dashboard"
                  element={<ProtectedRoute userTypeAllowed={["tanod"]}><Dashboard /></ProtectedRoute>}
                />
                <Route
                  path="/patrolmap"
                  element={<ProtectedRoute userTypeAllowed={["tanod"]}><Patrolmap /></ProtectedRoute>}
                />
                <Route
                  path="/equipments"
                  element={<ProtectedRoute userTypeAllowed={["tanod"]}><Equipments /></ProtectedRoute>}
                />
                <Route
                  path="/performance"
                  element={<ProtectedRoute userTypeAllowed={["tanod"]}><Performance /></ProtectedRoute>}
                />
                <Route
                  path="/schedule"
                  element={<ProtectedRoute userTypeAllowed={["tanod"]}><Schedule /></ProtectedRoute>}
                />
                <Route
                  path="/incidents"
                  element={<ProtectedRoute userTypeAllowed={["tanod"]}><Incidents /></ProtectedRoute>}
                />
                
              </Route>

              {/* Protected Routes for Residents */}
              <Route element={<Layout />}>
                <Route
                  path="/resident-dashboard"
                  element={<ProtectedRoute userTypeAllowed={["resident"]}><ResidentDashboard /></ProtectedRoute>}
                />
                <Route
                  path="/ratetanod"
                  element={<ProtectedRoute userTypeAllowed={["resident"]}><ResidentRating /></ProtectedRoute>}
                />
              </Route>
            </Routes>
          </Suspense>
        </CombinedProvider>
      </BrowserRouter>
    </div>
  );
}

export default App;


ProtectedRoute.js

import React from "react";
import { Navigate } from "react-router-dom";
import { useCombinedContext } from "../contexts/useContext";

export default function ProtectedRoute({ userTypeAllowed, children }) {
  const { userType, token } = useCombinedContext();

  if (!token || !userTypeAllowed.includes(userType)) {
    return <Navigate to="/" />;
  }
  
  return children;
}

useContext.js

import React, { createContext, useState, useEffect, useContext, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { toast } from 'react-toastify'; 

export const CombinedContext = createContext();

export const CombinedProvider = ({ children }) => {
  const [token, setToken] = useState(localStorage.getItem('token'));
  const [userType, setUserType] = useState(null); 
  const navigate = useNavigate();

  const fetchData = useCallback(async () => {
    // Fetch user data to get userType
  }, []);

  useEffect(() => {
    if (token) {
      fetchData();
    }
  }, [token, fetchData]);

  const logout = () => {
    localStorage.removeItem('token');
    setToken(null);
    setUserType(null);
    navigate('/');
  };

  return (
    <CombinedContext.Provider value={{ token, userType, logout }}>
      {children}
    </CombinedContext.Provider>
  );
};

export const useCombinedContext = () => useContext(CombinedContext);

reactjs authentication react-router jwt access-token
1个回答
0
投票

听起来您正在处理 React 应用程序中的状态持久性问题。以下是一些建议,可帮助您在刷新后保持当前状态,防止受保护和不受保护的路由重定向到根路径(“/”):

1。在本地存储中保留用户状态 确保您的用户状态(令牌和用户类型)正确保留在本地存储中并在应用程序加载时重新水合。

在 useContext.js 中,您已经将令牌存储在本地存储中。确保您还存储了 userType。

2。检查路线更改的用户状态 确保您的 ProtectedRoute 组件在渲染受保护的组件之前正确检查用户状态。

  1. 应用程序加载时的补水状态 确保您的应用程序在加载时从本地存储中重新恢复状态。您可以在您的 JointProvider 中执行此操作。

import React, { createContext, useState, useEffect, useContext, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { toast } from 'react-toastify'; 

export const CombinedContext = createContext();

export const CombinedProvider = ({ children }) => {
  const [token, setToken] = useState(localStorage.getItem('token'));
  const [userType, setUserType] = useState(localStorage.getItem('userType')); 
  const navigate = useNavigate();

  const fetchData = useCallback(async () => {
    // Fetch user data to get userType
  }, []);

  useEffect(() => {
    if (token) {
      fetchData();
      localStorage.setItem('userType', userType);
    }
  }, [token, userType, fetchData]);

  useEffect(() => {
    const storedToken = localStorage.getItem('token');
    const storedUserType = localStorage.getItem('userType');
    if (storedToken) {
      setToken(storedToken);
    }
    if (storedUserType) {
      setUserType(storedUserType);
    }
  }, []);

  const logout = () => {
    localStorage.removeItem('token');
    localStorage.removeItem('userType');
    setToken(null);
    setUserType(null);
    navigate('/');
  };

  return (
    <CombinedContext.Provider value={{ token, userType, logout }}>
      {children}
    </CombinedContext.Provider>
  );
};

export const useCombinedContext = () => useContext(CombinedContext);

© www.soinside.com 2019 - 2024. All rights reserved.