RouterGuard with react-router5

作用

  • 阻止页面越权
  • 不用调用接口即可阻止页面越权
    例如:某普通管理员登录,即使知道超管的页面路由地址,也看不到越权的页面。

实现

参考reactrouter官方教程,结合路由嵌套配置,和路由鉴权示例。

https://reactrouter.com/web/example/auth-workflow
https://reactrouter.com/web/example/route-config

代码

  1. router.js 路由配置(增加权限字段)
import MainPart from '../pages/Layout/MainPart';
import Login from '../pages/login/Index.jsx';
import LiveList from '../pages/LiveList/Index.jsx';
import Authority from '../pages/Authority/Index.jsx';
import LiveDetail from '../pages/LiveDetail/Index.jsx';
export default [
        {
            path: '/',
            component: Login,
            exact: true
        },
        {
            path: '/login',
            component: Login
        },
        {
            component: MainPart,
            routes: [
                {
                    path: '/authority',
                    component: Authority,
                    auth:[99,98]
                },
                {
                    path: '/liveList',
                    component: LiveList,
                    auth:[97,98,99]
                },
                {
                    path: '/liveDetail',
                    component: LiveDetail,
                },
            ]
        },
];
  1. index.js 引入组件
import React, {useReducer,Fragment } from 'react';
import {HashRouter as Router, Route, Switch,Redirect, } from 'react-router-dom';
import ReactDom from 'react-dom';
import routers from './router';
import {defaultState, reducer, COMMON_CONTEXT} from './COMMON/store';
import RouterGuard from './RouterGuard.js';


function Index() {
    const [state, dispatch] = useReducer(reducer, defaultState);
    return (
        
            
                
                    {routers.map((route, i) => (
                        
                    ))}
                
            
        );
}

document.title = '和家亲直播能力平台';
ReactDom.render(, document.querySelector('#app'));
  1. RouterGuard.js 增加拦截逻辑
function RouterGuard(route) {
  const {state} = useContext(COMMON_CONTEXT);
  console.log(state);
  return (
    
     (
          route.auth?.indexOf(Number(state.authCode))==-1?
          :
          
        )}
      />
    );
  }
  
  export default RouterGuard;
  1. 嵌套路由处理
            
                
                
                    
                        {routes.map((route, i) => (
                            
                        ))}
                    
                
            
  1. 登录后,保存权限配置
const {dispatch} = useContext(COMMON_CONTEXT);
const function loginApi=()=>{
        //省略登录逻辑代码
        dispatch({
                authToken,
                authUserCode: userCode,
                authCode,
                authRole,
                authPhone
            });
}

HOOKS 相关知识点

useContext与useReducer 代替 redux

  1. useContext

const value = useContext(MyContext);
接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的 的 value prop 决定。
当组件上层最近的 更新时,该 Hook 会触发重渲染,并使用最新传递给 MyContext provider 的 context value 值。

const themes = {
  light: {
    foreground: "#000000",
    background: "#eeeeee"
  },
  dark: {
    foreground: "#ffffff",
    background: "#222222"
  }
};

const ThemeContext = React.createContext(themes.light);

function App() {
  return (
    
      
    
  );
}

function Toolbar(props) {
  return (
    
); } function ThemedButton() { const theme = useContext(ThemeContext); return ( ); }
  1. useReducer
const [state, dispatch] = useReducer(reducer, initialArg, init);

useState 的替代方案。它接收一个形如 (state, action) => newState 的 reducer,并返回当前的 state 以及与其配套的 dispatch 方法。(如果你熟悉 Redux 的话,就已经知道它如何工作了。)

在某些场景下,useReducer 会比 useState 更适用,例如 state 逻辑较复杂且包含多个子值,或者下一个 state 依赖于之前的 state 等。并且,使用 useReducer 还能给那些会触发深更新的组件做性能优化,因为你可以向子组件传递 dispatch 而不是回调函数 。

以下是用 reducer 重写 useState 一节的计数器示例:

const initialState = {count: 0};

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      
      
    
  );
}

你可能感兴趣的:(RouterGuard with react-router5)