- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
MERN APP(MongoDB、Express、ReactJS、NodeJS)- 在后端,我使用 token 控制登录用户并根据角色授予用户访问权限。
问题是:如果用户是管理员或客户端,如何控制前端(ReactJS)用户的角色?
例如:如果用户已登录,我会从后端向前端发送一个 token ,如果用户已登录,我可以像这样控制路由:
if(token){ //if user is logged
<Route path="/dashboard" exact>
<Products/> //Products Page
</Route>
}else{
<Route path="/dashboard" exact>
<Page1 /> //AnyPage
</Route>
}
我只想为管理员用户授予访问用户页面的权限:
if(token && role === 'admin'){ //if user is logged and role is admin
<Route path="/dashboard" exact>
<Users /> //Users Page
</Route>
}...
我可以在后端控制这个东西,我只想在前端对这个问题有任何其他想法。谢谢:)
最佳答案
遇到这种情况我会怎么做:
当用户登录时,API 应返回他们的信息,包括权限。将该信息存储在状态中。
创建一个函数,checkUserPermission(user = { roles: [] }, permission)
。此函数接受 user
对象、permission
字符串(即 "route.admin"
、"component.Authenticate"
)并应根据用户的访问级别返回 true 或 false。那将是一个决定当前用户是否被允许做这个或那个的地方。它可以包含简单的属性检查(if (user.role === 'admin')
)或更复杂的内容(查看示例)。
创建 SecuredRoute
组件,它是 Route
的包装器,但需要 user
和 permission
参数和如果用户看不到这条路线,则重定向离开。
使用 checkUserPermission
函数有条件地呈现链接或组件。
正如在其他答案中已经提到的,API 必须对每个请求进行自己的权限检查,因为在 UI 端隐藏内容不会阻止恶意和知识渊博的用户
//src/utils/checkUserPermission.js
export default function checkUserPermission(user = { roles: [] }, permission) {
const allowAccessForRoles = {
"route.admin": ["admin"],
"route.authenticated": ["user", "admin"],
"route.home": ["*"], //means "Any role"
"component.Authenticate": ["*", "!user", "!admin"], //Any role except user and admin
"component.BecomeAdmin": ["user"],
"component.LogOut": ["user", "admin"]
};
//If we don't have such permission in list, access denied for everyone
if (!Array.isArray(allowAccessForRoles[permission])) {
return false;
}
//Check if any of user's roles explicitly denies access
for (const role of user.roles) {
if (allowAccessForRoles[permission].includes("!" + role)) {
return false;
}
}
//If list of allowed roles contains '*', access allowed for everyone
if (allowAccessForRoles[permission].includes("*")) {
return true;
}
//Check if any of user's roles allowes access
for (const role of user.roles) {
if (allowAccessForRoles[permission].includes(role)) {
return true;
}
}
return false;
}
//src/SecuredRoute
import React from "react";
import { Route, Redirect } from "react-router-dom";
import checkUserPermission from "./utils/checkUserPermission";
const SecuredRoute = ({
user,
permission,
redirectTo = "/",
children,
...rest
}) => {
const allowed = checkUserPermission(user, permission);
if (allowed) {
return <Route {...rest} render={() => children} />;
}
return (
<Route
{...rest}
render={({ location }) => (
<Redirect
to={{
pathname: redirectTo,
state: { from: location }
}}
/>
)}
/>
);
};
export default SecuredRoute;
//src/App.js
import React, { useState } from "react";
import "./styles.css";
import { BrowserRouter as Router, Switch, Link } from "react-router-dom";
import SecuredRoute from "./SecuredRoute";
import checkUserPermission from "./utils/checkUserPermission";
const AdminPage = () => <div>Admin page is open for admins</div>;
const AuthenticatedPage = () => (
<div>Authenticated page is open for users and admins</div>
);
const HomePage = () => <div>Home page is open for everyone</div>;
export default function App() {
const [user, setUser] = useState();
return (
<Router>
<div className="App">
<div className="Nav">
<div>
<Link to="/">Go to Home Page</Link>
</div>
{checkUserPermission(user, "route.authenticated") ? (
<div>
<Link to="/authenticated">Go to Authenticated Page</Link>
</div>
) : null}
{checkUserPermission(user, "route.admin") ? (
<div>
<Link to="/admin">Go to Admin Page</Link>
</div>
) : null}
</div>
<div className="Controls">
{checkUserPermission(user, "component.Authenticate") ? (
<button type="button" onClick={() => setUser({ roles: ["user"] })}>
Become authenticated
</button>
) : null}
{checkUserPermission(user, "component.BecomeAdmin") ? (
<button type="button" onClick={() => setUser({ roles: ["admin"] })}>
Become admin
</button>
) : null}
{checkUserPermission(user, "component.LogOut") ? (
<button type="button" onClick={() => setUser()}>
Log out
</button>
) : null}
</div>
<div className="Main">
<Switch>
<SecuredRoute user={user} permission="route.home" exact path="/">
<HomePage />
</SecuredRoute>
<SecuredRoute
user={user}
permission="route.authenticated"
path="/authenticated"
>
<AuthenticatedPage />
</SecuredRoute>
<SecuredRoute user={user} permission="route.admin" path="/admin">
<AdminPage />
</SecuredRoute>
</Switch>
</div>
</div>
</Router>
);
}
关于reactjs - 如何在前端 React JS 上控制用户角色 - MERN 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59957892/
我是 Node 和 react 新手,我正在尝试在我的 MERN 应用程序中进行子域路由。我发现我无法在 react 中路由我的子域,所以这让我只剩下 Node 。在node中,有很多方法,比如vho
我正在使用技术堆栈 MERN 创建一个应用程序和 Redux .我想知道如何使用 moongose 检索最后添加到数据库的记录.例如,假设它将是分配给特定用户的订单列表。 我已经在后端完成了一个检索所
我正在构建一个基于 MERN Stack 的费用控制应用程序,我想知道哪种方式是处理数据的最佳方式。 更具体地说,我的费用数据具有以下模型 { "_id" : ObjectId("5ece
我正在尝试根据查询从 Mongo db 获取一些记录。我完成了后端,它与 Postman 配合得很好,但我不知道如何将查询的变量从 React 前端发送到后端。 有一个 Client 模型类,我想检索
我正在尝试更新帖子。后端的 PUT 请求工作正常,在 Postman 上测试时返回 200 并更新帖子,但是当我尝试在前端更新帖子( react )时,我没有收到任何错误,但更新的帖子没有被更新提交和
当我重新加载 Heroku 页面时,出现内部服务器错误,状态代码为 500。 但在我本地的环境中并没有发生这种情况。 除此之外, 当我访问正确重定向并正常显示的路由地址时。 当我重新加载页面时,在 c
我在前端连接了 mongoDB 和 react/redux 的 node/express api。 我如何向用户显示错误(例如数据库连接错误)。 例如,如果后端发生错误,我想在组件中创建带有错误消息的
我正在尝试弄清楚如何有条件地渲染部分 react 。我的条件是,当列表项处于事件状态时,应呈现部分内容。 我正在使用 bootstrap,它有一个可用的事件元素。 我的目标是实现类似于对讲机条款页面的
我的应用程序概览:用户可以提交包含图片和文字的帖子。 我正在使用 MERN 堆栈。 目前,图像正在保存到我的 localhost:3001 中服务器在 /public/uploads/然后将路线保存到
我在 React 中得到了带有表单的简单 MERN 堆栈应用程序,它将字段传递给 redux 状态。 Redux 与后端的 node/express 连接,将数据保存在 MongoDB 中。 表单需要
我需要使用像这样的 mongodb 记录: { "_id": { "$oid": "5c09ae281646e8d8bad07d73" }, "name": "
我正计划将 MERN 堆栈应用程序部署到 heroku(在 youtube 上跟随 Traversy Media),我想知道在客户端隐藏 api key (谷歌地图)的最佳做法是什么? 我知道如何在
我是 Web 开发新手,我有一个托管服务,我想在其上部署我的 ReactJS/Node 项目。之前为了部署它,我只是上传了通过运行 npm run build 创建的构建文件夹。此后,我使用 MERN
我使用 create-react-app 制作了一个非常简单的 MERN 应用程序,没有 mongo 数据库。当我部署到 heroku 时,我看到的只是一个空白页面。我已经尝试了很多没有运气的事情。
我尝试在 MEAN.js 中包含一个中间件 (passport-http-bearer),但它使用与 Express 4 不同的路由语法。 Express API 语法是: app.get('/',
我正在部署 MERN 应用程序,并正在寻找有关构建 API 与 React 路由相对路径的最佳方法的指导。以下是我的两条路线的子集。我的相对路线复制了文件夹结构,我不确定如何解决这个问题。 用户路由
我第一次使用 MERN 堆栈构建应用程序。 为了记录 HTTP 请求,我使用“morgan”。 我设法将数据发送到 mongodb,它似乎工作正常。问题是我的帖子请求没有通过。它显示“待处理”4 分钟
我正在考虑将 MERN 框架用于一个新项目,但到目前为止,我所看到的并没有让我感到鼓舞。我已按照通过 mern-cli 设置项目的说明进行操作,该项目确实已创建并正确运行,但当我执行时... npm
我使用 Node、Express、React 和 MongoDB 创建了一个简单的计费 Web 应用程序 但是我想将它转换为本地机器的桌面应用程序。 我知道可以使用 Electron ,但我不知道该怎
我正在尝试将我的 MongoDB 连接到我的 MERN Web 应用程序,并且想知道有关此类信息的最佳资源。基本上,我有一个 MERN Web 应用程序、 Electron 桌面应用程序和 react
我是一名优秀的程序员,十分优秀!