Я думаю, вам следует значительно упростить структуру маршрутов, где вы сначала включаете свои аутентифицированные маршруты в ProtectedRoutes
HOC.Этот маршрут позволяет только авторизованным (авторизованным) пользователям просматривать его.Затем добавьте еще один RequireAdmin
HOC, чтобы проверить, равен ли role
admin
.Если нет, он перенаправляет на страницу NotFound
.
Аутентифицированный пользователь имеет доступ к /u/dashboard
, но когда он щелкает ссылку Admin Dashboard
, он показывает страницу NotFound
.Однако администратор имеет доступ к обоим!
Для проверки:
- нажмите
Login
- , войдите как
testuser123@example.com
с паролем 123456
- при перенаправлении попробуйте получить доступ к
Admin Dashboard
- перенаправлениям на
NotFound
страницу - нажмите
Go Back
- нажмите
Dashboard
- нажмите
Logout
- нажмите
Login
еще раз. - войдите как
admin@example.com
с паролем 123456
- при перенаправлении нажмите
User Dashboard
и Admin Dashboard
(обе работы)
Рабочий пример :
контейнеры / ProtectedRoutes
import isEmpty from "lodash/isEmpty";
import React, { Component, Fragment } from "react";
import { connect } from "react-redux";
import { withRouter } from "react-router-dom";
import Navigation from "../../components/Website/Navigation";
class ProtectedRoutes extends Component {
componentDidMount = () => {
if (isEmpty(this.props.user) || !this.props.user.email) {
this.props.history.push("/notfound");
}
};
componentDidUpdate = prevProps => {
if (this.props.user !== prevProps.user) {
this.props.history.push("/notfound");
}
};
render = () =>
this.props.user.email ? (
<Fragment>
<Navigation />
{this.props.children}
</Fragment>
) : null;
}
export default connect(state => ({ user: state.user }))(
withRouter(ProtectedRoutes)
);
контейнеры / RequireAdmin
import isEmpty from "lodash/isEmpty";
import { Component } from "react";
import { connect } from "react-redux";
import { withRouter } from "react-router-dom";
class RequireAdmin extends Component {
componentDidMount = () => {
if (isEmpty(this.props.user) || this.props.user.role !== "admin") {
this.props.history.push("/notfound");
}
};
componentDidUpdate = prevProps => {
if (this.props.user !== prevProps.user) {
this.props.history.push("/notfound");
}
};
render = () =>
isEmpty(this.props.user) || this.props.user.role === "admin"
? this.props.children
: null;
}
export default connect(state => ({ user: state.user }))(
withRouter(RequireAdmin)
);
маршруты (основной)
import React from "react";
import { Route, Switch } from "react-router-dom";
import ProtectedRoutes from "../containers/ProtectedRoutes";
import Admin from "../components/Admin";
import Home from "../pages/Website/Home";
import NotFound from "../pages/Website/NotFound";
import LoginForm from "../containers/LoginForm";
import RegisterForm from "../containers/RegisterForm";
import User from "../components/User";
const Routes = () => (
<div>
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/login" component={LoginForm} />
<Route exact path="/register" component={RegisterForm} />
<Route exact path="/notfound" component={NotFound} />
<ProtectedRoutes>
<Route path="/u" component={User} />
<Route path="/a" component={Admin} />
</ProtectedRoutes>
</Switch>
</div>
);
export default Routes;
компоненты / пользователь (маршруты, защищенные пользователем)
import React, { Fragment } from "react";
import { Route, Switch } from "react-router-dom";
import Dashboard from "../../pages/User/Dashboard";
import NotFound from "../../pages/Website/NotFound";
const User = ({ match }) => (
<Fragment>
<Switch>
<Route exact path={`${match.url}/dashboard`} component={Dashboard} />
<Route path={`${match.url}`} component={NotFound} />
</Switch>
</Fragment>
);
export default User;
компоненты / администратор (маршруты, защищенные администратором)
import React, { Fragment } from "react";
import { Route, Switch } from "react-router-dom";
import RequireAdmin from "../../containers/RequireAdmin";
import Dashboard from "../../pages/Admin/Dashboard";
import NotFound from "../../pages/Website/NotFound";
const Admin = ({ match }) => (
<RequireAdmin>
<Switch>
<Route exact path={`${match.url}/dashboard`} component={Dashboard} />
<Route path={`${match.url}`} component={NotFound} />
</Switch>
</RequireAdmin>
);
export default Admin;