我有一个基本的管理员应用程序,当用户通过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组件上的道具。
答案 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()