likes
comments
collection
share

🎉🎉🎉一文全面了解:一个神奇的 react-antd-admin 鉴权方式

作者站长头像
站长
· 阅读数 10

这是上一篇文章:

React Router v6 带来了一些改变,包括鉴权的处理方式也有所不同。在后台管理系统中进行路由鉴权通常涉及到以下步骤:

  1. 定义路由表: 首先,你需要定义一个路由表,包括所有的页面和它们对应的路径。这可以在一个单独的文件中完成,例如 routes.js
import { Route, Outlet } from 'react-router-dom';

const routes = [
  {
    path: '/',
    element: <DashboardLayout />, // 主要布局组件
    children: [
      { path: 'dashboard', element: <DashboardPage /> },
      { path: 'users', element: <UsersPage /> },
      // 其他页面
    ],
  },
  {
    path: '/login',
    element: <LoginPage />,
  },
  // 其他路由
];

export default routes;
  1. 创建路由守卫(Guard): 使用 React Router 提供的 <Route> 组件,你可以创建路由守卫来检查用户是否已经登录或拥有访问特定页面的权限。这通常涉及到一个函数,用于进行鉴权检查,并根据鉴权结果来渲染页面或执行重定向。例如:
import { Route, Navigate } from 'react-router-dom';

const PrivateRoute = ({ element, auth }) => {
  return auth.isAuthenticated ? (
    element
  ) : (
    <Navigate to="/login" replace />
  );
};

在上述示例中,如果用户已经登录(auth.isAuthenticatedtrue),则渲染传入的 element,否则将用户重定向到登录页面。

  1. 应用路由守卫: 将路由守卫应用到你的路由表中。在路由表中的需要鉴权的路由上使用 <PrivateRoute>
import { Route, Routes } from 'react-router-dom';

const App = () => {
  return (
    <Routes>
      {routes.map((route, index) => (
        <Route
          key={index}
          path={route.path}
          element={<PrivateRoute element={route.element} auth={auth} />}
        />
      ))}
    </Routes>
  );
};
  1. 管理用户认证状态: 在你的应用中,你需要实现用户的认证状态管理逻辑。这可以包括登录、登出、以及检查用户是否已经登录的功能。

这只是一个简单的示例,实际中可能需要更复杂的鉴权逻辑,比如基于用户角色的权限管理等。总之,React Router v6 仍然可以用于构建强大的后台管理系统,但你需要调整你的代码以适应这个新版本的 API。鉴权通常是这类系统中一个重要的部分,需要仔细设计和实现。

按照上面的方式,react-antd-admin 后台管理系统会封装一个高阶的函数组件 auth.tsx,这个组件用来鉴权是否已经登录,如果登录这直接跳转响应的页面,如果没有登录则跳转到登录页面

  • 页面没清缓存刷新
  • 页面清缓存刷新
// 判断token是否存在,如果存在正常渲染,如果不存在重定向到登录路由
import React from 'react'
import { getItem } from "@/utils/storage";
import { Routes, Route } from "react-router-dom";
import Login from '@/pages/login';
import Register from '@/pages/register';
import Loading from '../loading';


const Auth = ({ children }: any) => {
    // 通过获取响应的登录 token,来判断是否登录,登录直接执行 {children}
    const isToken = getItem('token')
    if (isToken) {
        return (
            <>
                {children}
            </>
        )
    } else {
        // 定向到注册登录
        // 这里实际上有两点,这注册页面,跟登录页面是公共页面,
        // 解决了页面刷新判断,用户手动清除缓存之后刷新页面
        return (
            <React.Fragment>
                <React.Suspense fallback={<Loading />}>
                    <Routes>
                        <Route path='/login' element={<Login />} />
                        <Route path='/register' element={<Register />} />
                    </Routes>
                </React.Suspense>
            </React.Fragment>
        )
    }
}
export default Auth

react-antd-admin 对应的 App.tsx 组件如下

其中 mainApp 是我们项目的 layout 组件,包括左侧菜单,顶部,主显示区,这个我们后面再说

App.tsx 这个组件我们主要针对登录之后,刷新的时候,会判断 token 是否存在,如果不存在,就会直接跳转到登录页面

import React, { useEffect, useState, Suspense } from 'react';
import './app.less';
import './assets/style/reset.less';
import MainApp from './components/layout';
import Auth from './components/auth';
import { getMenu } from '@/api/module/user/menu';
import Loading from './components/loading';
import { getItem } from './utils/storage';
import { useNavigate, useLocation } from 'react-router';
export default function App() {
  const [dynamicMenuData, setDynamicMenuData] = useState<any[]>([])
  const navigate = useNavigate()
  const { pathname } = useLocation()

  useEffect(() => {
    getMenu().then(res => {
      setDynamicMenuData(res.data as any[])
    })

    // 判断登录跳转
    const isToken = getItem('token')
    if (!isToken && (pathname !== '/login' && pathname !== '/register')) {
      navigate('/login', { replace: true })
    }
  }, [])

  return (
    <Suspense fallback={<Loading />}>
      {
        dynamicMenuData && dynamicMenuData.length
          ?
          <Auth children={<MainApp dynamicMenuData={dynamicMenuData} />} />
          : <Loading />
      }
    </Suspense>
  )
}