我有一个node.js后端,该后端具有一个登录/注册和几个URL,它们可以通过各自的角色进行访问。例如,我已经测试了该URL http://localhost:5000/api/deleteuser:user_id,并且只有具有角色“ ADMIN”的用户和具有相同访问控制的其他路由的用户才能访问该URL
在我的react-redux应用程序中,我设法创建使用jwt的登录/注册,但是在用户使用其用户名和密码登录后,系统仅将其定向到仪表板。我想在用户尝试登录时检查用户角色,以便如果他是管理员,那么系统会将他定向到管理页面,或者如果他也是一名教师,也将其定向到教师的页面,依此类推。
目前,我正在努力思考如何解决该问题。 我试图用CASL做出反应,但是我听不懂,所以请您帮我
提前感谢
我尝试使用CASL https://www.npmjs.com/package/@casl/react,但我听不懂。
export const userSignin = (userData, history) => {
return dispatch => {
axios.post('/api/signin', userData)
.then(res => {
//success message
toastr.success('Welcome')
//redirect to dashboard
//save token to location storage
const { token } = res.data;
localStorage.setItem('jwtToken', token);
//set token to auth header
setAuthToken(token);
//decode token
const jwtDecoded = jwtDecode(token);
if(res.data.role === 'admin'){
history.push('/admin');
}else{
history.push('/dashboard');
}
//set current user
dispatch(setCurrentUser(jwtDecoded));
})
.catch(error => dispatch({
type: GET_ERRORS,
payload: error.response.data
}))
}
}
class Signin extends React.Component {
state = {
username: '',
password: '',
usernameError: '',
passwordError: '',
errors: {}
}
handleUsername = (e) => {
this.setState({ username: e.target.value }, () => { this.validateUsername() });
}
handlePassword = (e) => {
this.setState({ password: e.target.value }, () => { this.validatePassword() });
}
validateUsername = () => {
const { username } = this.state;
let usernameError;
if (username === '') {
usernameError = 'Username is required';
}
this.setState({ usernameError });
return !usernameError;
}
validatePassword = () => {
const { password } = this.state;
let passwordError;
if (password === '') {
passwordError = 'Password is required';
}
this.setState({ passwordError });
return !passwordError;
}
handleSubmit = (e) => {
e.preventDefault();
const validUsername = this.validateUsername();
const validPassword = this.validatePassword();
if (validUsername && validPassword) {
const userData = {
username: this.state.username,
password: this.state.password
}
this.props.userSignin(userData, this.props.history);
}
}
componentDidMount() {
if (this.props.auth.isAuthenticated) {
// const role = this.props.role;
// if (role === "Admin") {
// this.props.history.push('/admin');
// } else {
// this.props.history.push('/dashboard');
// }
this.props.history.push('/dashboard');
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.auth.isAuthenticated === true) {
this.props.history.push('/dashboard');
}
if (nextProps.errors) {
this.setState({ errors: nextProps.errors })
}
}
render() {
return (
<div className="container">
<div className="row">
<div className="col-sm-4 col-sm-offset-4">
{
this.state.errors.success === false ? <p className="text-danger text-center">{this.state.errors.message}</p> : null
}
</div>
<div className="col-sm-4 col-sm-offset-4">
<h3 className='text-center'>Login</h3>
<form onSubmit={this.handleSubmit}>
<div className={classnames('form-group', { 'has-error': this.state.usernameError })}>
<input
type="text"
className="form-control"
value={this.state.username}
onChange={this.handleUsername}
placeholder="Username"
/>
<span className="help-block">{this.state.usernameError}</span>
</div>
<div className={classnames('form-group', { 'has-error': this.state.passwordError })}>
<input
type="password"
className="form-control"
value={this.state.password}
onChange={this.handlePassword}
placeholder="Password"
/>
<span className="help-block">{this.state.passwordError}</span>
</div>
<button className="btn btn-success btn-sm">Login</button>
</form>
</div>
</div>
</div>
);
}
}
Signin.propTypes = {
auth: PropTypes.object.isRequired,
userSignin: PropTypes.func.isRequired
}
const mapStateToProps = (state) => {
return {
auth: state.auth,
errors: state.errors
}
}
export default connect(mapStateToProps, { userSignin })(withRouter(Signin));
exports.signin = (req, res) => {
User.findOne({ username: req.body.username }, function (err, user) {
if (err) throw err;
if (!user) {
res.status(401).json({ success: false, message: 'Auth failed,User not found' });
} else if (user) {
var validPassword = user.comparePassword(req.body.password);
if (!validPassword) {
res.status(401).json({ success: false, message: 'Auth failed,wrong password' });
} else {
var token = jwt.sign({
id: user._id,
username: user.username,
email: user.email,
password: user.password,
profileImage: user.profileImage,
created_at: user.created_at
}, config.secret, { expiresIn: '1h' });
res.status(200).json({ success: true, message: 'Authenticated', token: 'Bearer ' + token });
}
}
});
}
此刻仅将用户定向到仪表板,我想我在这里遗漏了一些东西
答案 0 :(得分:0)
在exports.signin
的最后一行中,您需要在要发回的对象中包含角色。例如,您发送的是:
res.status(200).json({ success: true, message: 'Authenticated', token: 'Bearer ' + token })
但是它必须是这样的:
res.status(200).json({ success: true, message: 'Authenticated', role: 'admin', token: 'Bearer ' + token })
然后在React中,确保您正在访问if statement
中的正确元素以推送到正确的路由。