zoukankan      html  css  js  c++  java
  • react-router 5.0 的鉴权

    react-router 5.0 的鉴权

    当我们使用react-router 控制页面的路由时候,有些页面,是需要登录才能访问,有些不需要登录就可以访问,还有些页面,是根据用户的权限来限制访问的。

    如果是传统的多页面,只需要后端鉴权就可以了,没权限就直接后端重定向。

    但是单页面情况下,路由使用了 window.history.statepush 这种情况下,路由的改变,是不会向服务器发送页面请求的。所以需要前端来鉴权


    一、参考vue的办法

    在vue 里面 路由配置为 json 格式,所以很方便的使用 路由守卫 , 来控制权限。所以网上有一种办法,就是利用 react-router-config 来模仿 vue的路由鉴权。

    其源码也不复杂。详细使用可以参考  。 通过研究以后发现,这似乎并不能满足我的要求,因为嵌套的子路由好像没有办法一次解决,也就是说,每个页面的嵌套子路由,要单独的配置json。并且似乎无法在父页面里面,对子页面的组件传props。

    二、自己写一个类似的 Route 组件,并在其里面鉴权

    新建一个 RouteGuard.tsx 源码如下。

    import * as React from 'react';
    import { Route, Redirect } from 'react-router-dom';
    
    // interface GuardProps {
    //     path:string;
    //     component:React.Component;
    //     permissions?:any[];
    //     exact?:boolean|undefined;
    //     strict?:boolean|undefined;
    //     otherProps?:object;
    // }
    
    // 可以由mobx注入用户信息
    class Guard extends React.Component<any, any> {
        constructor(props: any) {
            super(props);
            // 假设这里从 mobx 里面拿到了用户信息
            const userinfo = {
                level: 1 // 假设等级是一般用户
            };
            // 如果用户信息不存在,则需要去登录
            let auth = true;
            if (!userinfo) {
                auth = false;
            } else if (this.props.permissions) {
                // 如果存在,说明是需要区别等级鉴权的
                const permissions = this.props.permissions;
                if (permissions.indexOf(userinfo.level) === -1) {
                    auth = false;
                }
            }
            this.state = {
                auth
            };
        }
        public render() {
            const ComponentPage = this.props.component;
            return (
                <Route
                    path={this.props.path}
                    exact={this.props.exact || false}
                    strict={this.props.strict || false}
                    render={props => {
                        return (
                            this.state.auth ? (
                                <ComponentPage {...props} {...this.props.otherProps} />
                            ) : (
                                    <Redirect to={{
                                        pathname: '/login',
                                        state: { from: props.location }
                                    }} />
                                )
    
                        )
                    }
                    }
                />
            );
        }
    }
    export default Guard;
    

      

    使用方式与 Rute 类似,只要在需要鉴权的页面,使用RouteGuard  组件就可以了,如果不需要鉴权的,依然可以继续使用原生的 route 组件:

    import * as React from 'react';
    import { Switch } from 'react-router-dom';
    import RouteGuard from "src/RouteGuard";
    import Index from "src/pages/main/Index/Index";
    
    
    class Home extends React.Component<any>{
      public componentDidMount(){
        console.log(this.props);
      }
      public render() {
        return (
          <div className="_Home">
             <div className="section base-container">
              <Switch>
               <RouteGuard path="" exact={true} component={Index} />
              </Switch>
             </div>
          </div>
        );
      }
    }
    
    export default Home;
    

      

    总结:还可以继续加入一些判断,例如移动端和PC端的区别,来渲染不同的组件

  • 相关阅读:
    linux进程调度(zz)
    为什么vfork的子进程里用return,整个程序会挂掉,而且exit不会(zz)
    ubuntu安装samba
    【前端知乎系列】ArrayBuffer 和 Blob 对象
    【Web技术】442- 关于图片懒加载的几种方案
    【Web技术】441- 蚂蚁前端研发最佳实践
    【面试题】440- 10 道 Nodejs EventLoop 和事件相关面试题
    【面试题】439- 这是一道网红面试题
    【Web技术】438- 移动端体验优化经验总结与实践
    记 · 寒风依旧 · 虎跑路和人生路
  • 原文地址:https://www.cnblogs.com/muamaker/p/11531954.html
Copyright © 2011-2022 走看看