多用户登录身份验证| React Redux

时间:2019-05-24 12:39:38

标签: reactjs redux react-redux

我有一个具有多用户登录功能的应用程序。现在,我为登录功能创建了redux存储。如果用户登录,则根据其类型,它将重定向到特定的仪表板。如果学生用户登录,则他只能访问学生仪表板,而不能访问其他仪表板。其他也一样。但是,现在,如果有任何用户登录,他们便可以访问其他用户的仪表板。我如何防止他们仅使用仪表板。

/***AppRouter***/
    import React, {Component} from 'react';
    import { BrowserRouter, Route, Switch } from 'react-router-dom';
    import StuDashboard from '../views/ed/dashboard/Dashboard.js';
    import AdminDashboard from '../views/biz/dashboard/Dashboard.js';
    import OrgDashboard from '../views/org/dashboard/Dashboard.js';
    import SupAdDashboard from '../views/me/dashboard/Dashboard.js';
    import UserLogin from '../views/loginUser/Login.js';
    import history from '../history/history.js';
    import { PrivateRoute } from './PrivateRoute.js';
    import NotFoundPage from '../views/NotFoundPage.js';
    import Authorization from './Authorization';



    class AppRouter extends Component {
      render () {
        return(

          <BrowserRouter history={history}>
            <Switch>
              <Route path="/" component={Landing} exact />
              <Route path="/confirmation" component={EmailCon}/>
              <PrivateRoute path="/student/dashboard" component={Authorization(StuDashboard),["Student"]}/>
              <PrivateRoute path="/admin/dashboard" component={Authorization(AdminDashboard),["Admin"}/>
              <PrivateRoute path="/org/dashboard" component={Authorization(OrgDashboard),["Org"]}/>
              <PrivateRoute path="/SuperAdmin/dashboard" component={Authorization(SupAdDashboard),["SuperAdmin"]}/>
              <Route path="/login" component={UserLogin}/>  
              <Route path="" component={NotFoundPage} />
            </Switch>
          </BrowserRouter>

        );
      }
    }

    export default AppRouter;

/***PrivateRoute***/
import React from 'react';
import { Route, Redirect } from 'react-router-dom';

export const PrivateRoute = ({ component: Component, ...rest }) => (
    <Route {...rest} render={props => (
        localStorage.getItem('token')
            ? <Component {...props} />
            : <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
    )} />
)

/***Authorization***/
    import React, { Component } from 'react';
import { connect } from "react-redux";

const Authorization = (WrappedComponent, allowedRoles) =>{
   class WithAuthorization extends Component {
       render() {

     const { userType } = this.props.user
      if (allowedRoles.includes(userType)) {
        return <WrappedComponent {...this.props} />
      } else {
        return <h1>You are not allowed to view this page!</h1>
      }
    }
  }
const mapStateToProps = state => ({ user: state.login.userName, userType: state.login.userType })
return connect(mapStateToProps)(WithAuthorization);
}
export  default  Authorization;

/***Action.js***/
import axios from "axios";
import { LOGIN_PENDING, LOGIN_COMPLETED, LOGIN_ERROR, LOGOUT } from "./types";
import ApiUrl from "../../constants/ApiUrl.js";
import qs from "qs";
import history from '../../history/history.js';


const startLogin = () => {
  return {
    type: LOGIN_PENDING
  };
};

const loginComplete = data => ({
  type: LOGIN_COMPLETED,
  data
});

const loginError = err => ({
  type: LOGIN_ERROR,  
  err
});

export const loginUser = (email, password) => {
  return dispatch => {
    dispatch(startLogin());

    let headers = {
      "Content-Type": "application/x-www-form-urlencoded"
    };

    const data = qs.stringify({
      grant_type: "password",
      username: email,
      password: password,
    });

    axios
      .post(`${ApiUrl}/Token`, data, {
        headers: headers
      })

      .then(function (resp) {

        dispatch(loginComplete(resp.data));


       localStorage.setItem("token", resp.data.access_token);
      switch (resp.data.userType) {
        case 'Admin': {
          history.push('/admin/dashboard');
          break;
        }
        case 'Student': {
          history.push('/student/dashboard');
          break;
        }
        case 'Organization': {
          history.push('/org/dashboard');
          break;
        }
        case 'SuperAdmin': {
          history.push('/SuperAdmin/dashboard');
          break;
        }
        default:
         history.push('/');
      }
      window.location.reload();
      return;


})
      .catch(err => dispatch(loginError(err)));
  };
};

export const logOut = () => {
  localStorage.clear();
  return {
    type: LOGOUT,
  };
}

1 个答案:

答案 0 :(得分:1)

我添加了Authorization HOC来满足访问控制的需要。因此,您只需将组件和允许的角色传递给Authorization HOC。首先,我假设您的用户具有属性userType。请查看此URL

  /***Authorization***/
import React, { Component } from "react";
import { connect } from "react-redux";

const Authorization = (WrappedComponent, allowedRoles) => {
  class WithAuthorization extends Component {
    render() {
      const { userType } = this.props.userType;
      if (allowedRoles.includes(userType)) {
        return <WrappedComponent {...this.props} />;
      } else {
        return <h1>You are not allowed to view this page!</h1>;
      }
    }
  }
  const mapStateToProps = state => ({ user: state.login.userName, userType: state.login.userType })
  return connect(mapStateToProps)(WithAuthorization);
};
export default Authorization;

您的路由器将以这种方式显示

      <BrowserRouter history={history}>
        <Switch>
          <Route path="/" component={Landing} exact />
          <Route path="/confirmation" component={EmailCon}/>
          <PrivateRoute path="/student/dashboard" component={Authorization(StuDashboard,["Student"])}/>
          <PrivateRoute path="/admin/dashboard" component={Authorization(AdminDashboard,["Admin"])}/>
          <PrivateRoute path="/org/dashboard" component={ Authorization(OrgDashboard,["Organization"])}/>
          <PrivateRoute path="/SuperAdmin/dashboard" component={Authorization(SupAdDashboard,["SuperAdmin"])}/>
          <Route path="/login" component={UserLogin}/>  
          <Route path="" component={NotFoundPage} />
        </Switch>
      </BrowserRouter>