在React中授权多个角色的路由

时间:2016-12-18 04:31:26

标签: authentication reactjs routes

我正在遵循用于验证反应路由的教程,现在我可以允许用户在authenticated为真时访问路由。

routes.js

import React from 'react';
import { Route, IndexRoute,Redirect } from 'react-router';

import App from './app';
import requireAuth from '../Authentication/require_authentication';

import Dashboard from '../Dashboard';
import Managers from '../Managers';
import Guests from '../Guests';
import Login from '../Login';

export default (
  <Route path="/" component={App}>
    <IndexRoute component={requireAuth(Dashboard)} />
    <Route path="dashboard" component={requireAuth(Dashboard)} />    
    <Route path="advertisers" component={requireAuth(Managers)} />
    <Route path="properties" component={requireAuth(Guests)}/>
    <Route path="login" component={Login} />

  </Route>
);

require_authentication.js

/*HIGHER ORDER COMPONENT */
import React, { Component } from 'react';
import { connect } from 'react-redux';

export default function(ComposedComponent) {
  class Authentication extends Component {
    static contextTypes = {
      router: React.PropTypes.object
    }     

    componentWillMount() {
      if (!this.props.authenticated) {
        this.context.router.push('/login');
      }
    }

    componentWillUpdate(nextProps) {
      if (!nextProps.authenticated) {
        this.context.router.push('/login');
      }
    }          

    render() {
      return <ComposedComponent {...this.props} />
    }
  }

  function mapStateToProps(state) {
    return { authenticated: state.auth.authenticated };
  }

  return connect(mapStateToProps)(Authentication);
}

当用户登录时,他们将此作为localStorage中的状态:

userId: 1, 
userName:"Bob",
roleName:"Manager"

我对组成的组件还是比较新的,但我想知道是否有一种方法不仅可以进行身份​​验证,还可以阻止具有特定角色的用户访问路由。例如。经理应该只能看到经理路线和仪表板。客人只能看到仪表板和客人。

1 个答案:

答案 0 :(得分:1)

这绝对有可能,您只需要在检查授权后添加条件,该授权将检查用户的角色是否允许查看它尝试渲染的路由,如果不是,则可以将用户重定向到默认路由或显示的页面错误信息。

遵循require_authentication.js中的高阶组件的概念,这是一个应该做你想做的修改版本:

const checkPermissions = (userRole, router) => {
  if (userRole === "Manager") {
    if (!(router.isActive('/dashboard') ||
          router.isActive('/manager'))) {
      return false;
    }
  }
  return true;
};

export default function(ComposedComponent) {
  class Authentication extends Component {
    static contextTypes = {
      router: React.PropTypes.object
    }     

    componentWillMount() {
      if (!this.props.authenticated) {
        this.context.router.push('/login');
      } else if (!checkPermissions(this.props.user.role, this.context.router)) {
        this.context.router.push('/');
      }
    }

    componentWillUpdate(nextProps) {
      if (!nextProps.authenticated) {
        this.context.router.push('/login');
      } else if (!checkPermissions(this.props.user.role, this.context.router)) {
        this.context.router.push('/');
      }
    }          

    render() {
      return <ComposedComponent {...this.props} />
    }
  }

  function mapStateToProps(state) {
    return {
      authenticated: state.auth.authenticated,
      user: state.auth.user
    };
  }

  return connect(mapStateToProps)(Authentication);
}

checkPermission函数的实现可能不同且更易于配置,示例中的实现只是为了演示这个想法。

我假设您在auth对象内的状态中拥有授权用户数据。它可能会根据用户数据的存储位置进行更改。