通过React中的Route将变量传递给组件

时间:2015-08-25 12:56:33

标签: javascript reactjs flux

我有一个基本的管理员应用程序,当用户通过Oauth2协议登录时,我基本上想要保护某些路由免受API发送的角色。

我有一条路线......

<Route name="app" handler={App}>
   <Route name="admin" path="/admin" roles={["admin", "superadmin"]} />
</Route>

然后我有一个身份验证组件......

import React from 'react';
import SessionStore from '../stores/auth/SessionStore';

export default (ComposedComponent) => {

  return class AuthenticatedComponent extends React.Component {

    static willTransitionTo(transition) {

      // If user isn't logged in, send 'em back to the login page
      if (!SessionStore.isLoggedIn()) {
        transition.redirect('/login', {}, {'nextPath' : transition.path});
      } else if (this.rolesRequired) {

        // Get all current users roles from session store.
        let userRoles = SessionStore.roles;

        // Iterate through user roles, if none match the required roles, send 'em away ta.
        if (!this.rolesRequired.every(role => userRoles.indexOf(role) >= 0)) {
          transition.redirect('/login', {}, { 'nextPath' : transition.path }); 
        }
      }
    }

    constructor(props) {
      super(props);
      this.state = this._getLoginState();
    }

    _getLoginState() {
      return {
        userLoggedIn: SessionStore.isLoggedIn(),
        user: SessionStore.user,
        token: SessionStore.token,
        roles: SessionStore.roles
      };
    }

    componentDidMount() {
      this.changeListener = this._onChange.bind(this);
      SessionStore.addChangeListener(this.changeListener);
    }

    _onChange() {
      this.setState(this._getLoginState());    
    }

    componentsWillUnmount() {
      SessionStore.removeChangeListener(this.changeListener);
    }

    render() {
      return (
        <ComposedComponent
          {...this.props}
          user={this.state.user}
          token={this.state.token}
          roles={this.state.roles}
          userLoggedIn={this.state.userLoggedIn} />
      );    
    }
  }
}

然后,任何需要进行身份验证的组件都会传递给AuthenticatedComponent的实例,例如......

import React from 'react';
import RoleStore from '../../stores/user/RoleStore';
i
mport AdminActions from '../../actions/admin/AdminActions';
import AuthenticatedComponent from '../../components/AuthenticatedComponent';
import AdminMenu from '../../components/admin/AdminMenu';
import Template from '../template/BaseTemplate.react';
import RoleActions from '../../actions/user/RoleActions';

    /**
 * Admin
 *
 * @author    Ewan Valentine
 * @copyright 65twenty 2015
 */
export default AuthenticatedComponent(class Admin extends React.Component {

  constructor() {
    super();
    this.state = {
      users: [],
      roles: []
    };
    this.onChange = this.onChange.bind(this);
  }



  onChange() {
    this.setState({
      roles: RoleStore.data,
      users: UserListStore.data
    });  
  }

  render() {
    return(
          <Template>
          <main>
            <AdminMenu />
            <h2>Admin Home</h2>
          </main>
          </Template>
        );
      }
    });

我基本上无法找出定义所需角色的最佳方法,并且似乎没有任何方法可以访问Route组件上的道具。

1 个答案:

答案 0 :(得分:0)

我遇到了类似问题,如果用户属于“管理员”群组,我只想在顶部导航栏上显示“结算”链接。

我也有一个像你一样的身份验证组件,然后我根据所需的角色创建了一个授权组件和几个授权策略。这是代码:

var Authorized = require('../auth/Authorized');
var AdminComponentPolicy = require('../auth/policies/AdminComponentPolicy');

<Authorized policy={AdminComponentPolicy} action="show" user= {this.props.user}>
  ...protected stuff
</Authorized>

以下是授权组件的代码:

//Authorized.jsx
import React from 'react';

var Authorized = React.createClass({
  render: function() {
    //checks if the informed policy returns true for given action and user.
    if (this.props.policy.authorized(this.props.action, this.props.user)) {
      return this.props.children;
    } else {
      return null;
    }
  }
});
module.exports = Authorized;

以下是AdminComponentPolicy的代码

//AdminComponentPolicy.js
class AdminComponentPolicy {
  authorized(action, user) {
    //return user.role === 'admin';
    let _policies = {
      //the 'show' action in this policy returns true for 'admin' users
      show: function(record) {
         return record.role === 'admin';
      },
      destroy: function(record) {
         return this.show(record) || record.role === 'check if owner here';
      },
     };
    return _policies[action](user);
  }
}

export default new AdminComponentPolicy()