如何根据用户在此react-redux代码中的角色将用户重定向到特定的url

时间:2018-12-29 20:46:00

标签: node.js reactjs redux

我有一个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 });
      }
    }
  });
}

此刻仅将用户定向到仪表板,我想我在这里遗漏了一些东西

1 个答案:

答案 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中的正确元素以推送到正确的路由。