仅当用户具有管理员角色(React,Express,NodeJS,MongoDB)时访问页面

时间:2019-11-04 12:58:38

标签: node.js reactjs express

我想允许访问“用户”页面,该页面显示所有在网站上注册的用户,仅当该用户为admin时

这是页面的组成部分:

<Route path="/users" exact component={Users} />

我尝试了类似的方法,但是没有用:

Router.js

<AdminRoute path="/users" exact component={Users} />



AdminRoute/index.js

import React, { useEffect, useState } from "react";
import { Route, Redirect } from "react-router-dom";
import axios from "axios";
import M from "materialize-css";
import { connect } from "react-redux";

function AdminRoute({ component: Component, auth, ...rest }) {
  const [user, setUser] = useState(false);

  async function loadUser() {
    try {
      const dataUser = await axios.get(
        `http://localhost:5000/api/users/my-account/${auth.user.id}`
      );
      setUser(dataUser.data);
      console.log("user ", user); <-- returns well an object with isAdmin = 
      true
      M.AutoInit();
    } catch (error) {
      console.log(error);
    }
  }

  useEffect(() => {
    if (auth.isAuthenticated) {
      loadUser();
    }
  }, []);

  return (
    <Route
      {...rest}
      render={props =>
        auth.isAuthenticated && user.isAdmin ? (
          <Component {...props} />
        ) : (
          <Redirect to="/" />
        )
      }
    />
  );
}

const mapStateToProps = state => ({
  auth: state.auth
});
export default connect(mapStateToProps)(AdminRoute);

主要问题是,如果在使用管理员帐户时由于用户仍然为假而被重定向,那么我需要找到一种仅在loaduser功能完成后呈现组件的方法吗? < / p>

1 个答案:

答案 0 :(得分:0)

这是某种嵌套路线吗?我确定您可以将其设置为在您的路由页面上使用,但是我一直都使用真实性和声明来完成页面本身中的工作。

{isAdmin && <div />}

在组件上调用render()之前,您总是可以询问if (!isAdmin) props.history.push('/');

从“ react”导入React; 导入{   BrowserRouter作为路由器,   开关,   路线,   链接,   重定向   使用历史,   useLocation }来自“ react-router-dom”;

// This example has 3 pages: a public page, a protected
// page, and a login screen. In order to see the protected
// page, you must first login. Pretty standard stuff.
//
// First, visit the public page. Then, visit the protected
// page. You're not yet logged in, so you are redirected
// to the login page. After you login, you are redirected
// back to the protected page.
//
// Notice the URL change each time. If you click the back
// button at this point, would you expect to go back to the
// login page? No! You're already logged in. Try it out,
// and you'll see you go back to the page you visited
// just *before* logging in, the public page.

export default function AuthExample() {
  return (
    <Router>
      <div>
        <AuthButton />

        <ul>
          <li>
            <Link to="/public">Public Page</Link>
          </li>
          <li>
            <Link to="/protected">Protected Page</Link>
          </li>
        </ul>

        <Switch>
          <Route path="/public">
            <PublicPage />
          </Route>
          <Route path="/login">
            <LoginPage />
          </Route>
          <PrivateRoute path="/protected">
            <ProtectedPage />
          </PrivateRoute>
        </Switch>
      </div>
    </Router>
  );
}

const fakeAuth = {
  isAuthenticated: false,
  authenticate(cb) {
    fakeAuth.isAuthenticated = true;
    setTimeout(cb, 100); // fake async
  },
  signout(cb) {
    fakeAuth.isAuthenticated = false;
    setTimeout(cb, 100);
  }
};

function AuthButton() {
  let history = useHistory();

  return fakeAuth.isAuthenticated ? (
    <p>
      Welcome!{" "}
      <button
        onClick={() => {
          fakeAuth.signout(() => history.push("/"));
        }}
      >
        Sign out
      </button>
    </p>
  ) : (
    <p>You are not logged in.</p>
  );
}

// A wrapper for <Route> that redirects to the login
// screen if you're not yet authenticated.
function PrivateRoute({ children, ...rest }) {
  return (
    <Route
      {...rest}
      render={({ location }) =>
        fakeAuth.isAuthenticated ? (
          children
        ) : (
          <Redirect
            to={{
              pathname: "/login",
              state: { from: location }
            }}
          />
        )
      }
    />
  );
}

function PublicPage() {
  return <h3>Public</h3>;
}

function ProtectedPage() {
  return <h3>Protected</h3>;
}

function LoginPage() {
  let history = useHistory();
  let location = useLocation();

  let { from } = location.state || { from: { pathname: "/" } };
  let login = () => {
    fakeAuth.authenticate(() => {
      history.replace(from);
    });
  };

  return (
    <div>
      <p>You must log in to view the page at {from.pathname}</p>
      <button onClick={login}>Log in</button>
    </div>
  );
}

Click here for more info!