React Router Dom 受保护的路由在刷新页面时总是重定向到登录

React Router Dom Protected Route Always Redirects to Login during refresh page

我正在构建一个完整的堆栈反应应用程序。我已经实现了 React 路由器 v4 保护路由。一切顺利,但问题是用户登录后刷新 link 它重定向到登录页面。

这里是auth.js代码:用于登录和注销时检查身份验证。

class Auth {
  constructor() {
    this.authenticated = false;
  }

  login(cb) {
    this.authenticated = true;
    cb();
    console.log("login status"+this.authenticated)
  }

  logout(cb) {
    this.authenticated = false;
    cb();
  }

  isAuthenticated() {
    console.log("check status"+this.authenticated)
    return this.authenticated;
  }
}
export default new Auth();

这里是ProtectedRoute.js

import React from "react";
import { Route, Redirect,withRouter } from "react-router-dom";
import Auth from "./Auth";

const ProtectedRoute = ({component: Component,...rest}) => {
  return (
    <Route
      {...rest}
      render={props => {
        if (Auth.isAuthenticated()) {
          return <Component {...props} />;
        } else {
          return (
            <Redirect
              to={{
                pathname: "/admin/login",
                state: {
                  from: props.location
                }
              }}
            />
          );
        }
      }}
    />
  );
};
export default withRouter(ProtectedRoute);

这里是app.js

import React, { Component } from 'react';
import { BrowserRouter, Switch, Route} from 'react-router-dom';
import './css/style.css'
import './css/font-awesome.css'
import './css/jquery-ui.css'
import './App.css';
import './css/bootstrap.css'
import 'bootstrap'
import 'jquery'
import Login from './components/Login';
import Dashboard from './components/Dashboard'
import Users from './components/Users'
import UserProfile from './components/UserProfile';
import Categories from './components/Categories'
import ContactUs from './components/ContactUs'
import QueryDetails from './components/QueryDetails'
import EditProfile from './components/EditProfile'
import AdminProfile from './components/AdminProfile'
import ChangePassword from './components/ChangePassword'
import SaleOrPurchaseList from './components/SaleOrPurchaseList'
import ProductDetails from './components/ProductDetails'
import ReportList from './components/ReportList'
import NotFound from './components/NotFound'
import ProtectedRoute  from './components/ProtectedRoute';

class App extends Component {
  render() {
    return (
    <BrowserRouter>
      <Switch>
        <Route exact path="/admin/login" component={Login}/>
        <ProtectedRoute path='/admin/dashboard' component={Dashboard}/>
        <ProtectedRoute path='/admin/users' component={Users}/>
        <ProtectedRoute path='/admin/userProfile' component={UserProfile}/>
        <ProtectedRoute path='/admin/saleOrPurchaseList' component={SaleOrPurchaseList}/>
        <ProtectedRoute path='/admin/ProductDetails' component={ProductDetails}/>
        <ProtectedRoute path='/admin/categories' component={Categories}/>
        <ProtectedRoute path='/admin/reportList' component={ReportList}/>  
        <ProtectedRoute path='/admin/queries' component={ContactUs}/>
        <ProtectedRoute path='/admin/query_details' component={QueryDetails}/>
        <ProtectedRoute path='/admin/profile' component={AdminProfile}/>
        <ProtectedRoute path='/admin/edit_profile' component={EditProfile}/>
        <ProtectedRoute path='/admin/change_password' component={ChangePassword}/>
        <Route path="*" component={NotFound} />
      </Switch>
    </BrowserRouter> 
    );
  }
}

export default App;

this.authenticated 默认是 false 所以只要 ProtectedRoute 在调用 Auth.login 之前渲染它就会重定向到登录页面。您需要确保 this.authenticated 在渲染 ProtectedRoute.

之前获得正确的值

请注意,您的代码很可能在调用 Auth.loginAuth.logout 后不会触发 ProtectedRoute 的重新呈现。所以 ProtectedRoute 不会对 this.authenticated 变化做出反应。

您可以使用 localStorage 来处理身份验证。 在登录功能中,您可以像这样设置身份验证状态的值 localStorage.setItem('isAuth', authenticated)。在注销函数中 localStorage.removeItem('isAuth')。根据 localStorage

更改 PrivateRoute
import React from 'react';
import { Route, Redirect } from 'react-router-dom';

const PrivateRoute = ({
    component: Component,
    ...rest
}) => {
    const isAuth = localStorage.getItem('isLoggedIn');
    return (
        <Route
            {...rest}
            render={props =>
                isAuth ? (
                    <Component {...props} {...rest} />
                ) : (
                        <Redirect
                            to={{
                                pathname: "/admin/login",
                                state: {
                                  from: props.location
                                }
                            }}
                        />
                    )
                }
        />
    );
}

export default PrivateRoute;