一克拉的泪 發表於 2019-9-17 10:12:00

react-router 5.0 的鉴权

<h1>react-router 5.0 的鉴权</h1>
<p><span style="font-family: 宋体; font-size: 16px">当我们使用react-router 控制页面的路由时候,有些页面,是需要登录才能访问,有些不需要登录就可以访问,还有些页面,是根据用户的权限来限制访问的。</span></p>
<p><span style="font-family: 宋体; font-size: 16px">如果是传统的多页面,只需要<strong>后端鉴权</strong>就可以了,没权限就直接后端重定向。</span></p>
<p><span style="font-family: 宋体; font-size: 16px">但是单页面情况下,路由使用了<strong> window.history.statepush</strong> 这种情况下,路由的改变,是不会向服务器发送页面请求的。所以需要<strong>前端来鉴权</strong>。</span></p>
<h3><br>一、参考vue的办法</h3>
<p>在vue 里面 路由配置为 json 格式,所以很方便的使用 路由守卫 , 来控制权限。所以网上有一种办法,就是利用&nbsp;react-router-config 来模仿 vue的路由鉴权。</p>
<p>其源码也不复杂。详细使用可以参考&nbsp; 。 通过研究以后发现,这似乎并不能满足我的要求,因为嵌套的子路由好像没有办法一次解决,也就是说,每个页面的嵌套子路由,要单独的配置json。并且似乎无法在父页面里面,对子页面的组件传props。</p>
<p>&nbsp;</p>
<h3>二、自己写一个类似的&nbsp;Route 组件,并在其里面鉴权</h3>
<p>新建一个 RouteGuard.tsx 源码如下。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">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&lt;any, any&gt; {
    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 (
            &lt;Route
                path={this.props.path}
                exact={this.props.exact || false}
                strict={this.props.strict || false}
                render={props =&gt; {
                  return (
                        this.state.auth ? (
                            &lt;ComponentPage {...props} {...this.props.otherProps} /&gt;
                        ) : (
                              &lt;Redirect to={{
                                    pathname: '/login',
                                    state: { from: props.location }
                              }} /&gt;
                            )

                  )
                }
                }
            /&gt;
      );
    }
}
export default Guard;
</pre>
</div>
<p>  </p>
<p>使用方式与 Rute 类似,只要在需要鉴权的页面,使用<strong>RouteGuard&nbsp; </strong>组件就可以了,如果不需要鉴权的,依然可以继续使用原生的 route 组件:</p>
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">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&lt;any&gt;{
public componentDidMount(){
    console.log(this.props);
}
public render() {
    return (
      &lt;div className="_Home"&gt;
         &lt;div className="section base-container"&gt;
          &lt;Switch&gt;
         <strong>&lt;RouteGuard path="" exact={true} component={Index} /&gt;</strong>
          &lt;/Switch&gt;
         &lt;/div&gt;
      &lt;/div&gt;
    );
}
}

export default Home;
</pre>
</div>
<p>  </p>
<p>&nbsp;</p>
<p><strong>总结:</strong>还可以继续加入一些判断,例如移动端和PC端的区别,来渲染不同的组件</p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/muamaker/p/11531954.html
頁: [1]
查看完整版本: react-router 5.0 的鉴权