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端的區別,來渲染不同的組件

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM