Reactjs 如何控制前端React JS-MERN应用程序上的用户角色
MERN应用程序(MongoDB、Express、ReactJS、NodeJS)-在后端,我使用令牌控制登录用户,并根据角色授予用户访问权限 问题是:如果用户是管理员或客户端,如何控制前端(ReactJS)用户的角色 例: 如果用户已登录,我会将令牌从后端发送到前端,如果用户已登录,我可以控制如下路由:Reactjs 如何控制前端React JS-MERN应用程序上的用户角色,reactjs,Reactjs,MERN应用程序(MongoDB、Express、ReactJS、NodeJS)-在后端,我使用令牌控制登录用户,并根据角色授予用户访问权限 问题是:如果用户是管理员或客户端,如何控制前端(ReactJS)用户的角色 例: 如果用户已登录,我会将令牌从后端发送到前端,如果用户已登录,我可以控制如下路由: if(token){ //if user is logged <Route path="/dashboard" exact
if(token){ //if user is logged
<Route path="/dashboard" exact>
<Products/> //Products Page
</Route>
}else{
<Route path="/dashboard" exact>
<Page1 /> //AnyPage
</Route>
}
if(token){//if用户已登录
//产品页
}否则{
//任意页
}
我只想让管理员用户访问用户页面:
if(token && role === 'admin'){ //if user is logged and role is admin
<Route path="/dashboard" exact>
<Users /> //Users Page
</Route>
}...
if(令牌和角色==='admin'){//如果用户已登录且角色为admin
//用户页面
}...
我可以在后端控制这件事,我只想在前端了解关于这个问题的任何其他想法。
谢谢:)你的思路大体正确。这种模式(检测登录和/或角色状态以及有条件地呈现组件)通常称为“受保护路由” 你可以这样做:
const ProtectedRoute = ({showRoute, ...props}) => {
if (showRoute) {
return <Route {...props} />
} else {
// return null to simply not render the route if not logged in
return null;
// or you could return <Redirect to='/foo' /> to send them elsewhere
}
}
const App = () => {
const isLoggedIn = true;
return (
<Router>
<ProtectedRoute showRoute={isLoggedIn} path="/dashboard" component={Users} />
</Router>
);
}
在这种情况下我会做什么:
checkUserPermission(user={roles:[]},permission)
。此函数接受用户
对象、权限
字符串(即“route.admin”
、“component.Authenticate”
)并根据用户的访问级别返回true或false。这将是一个决定是否允许当前用户这样做或那样做的地方。它可以由简单的属性检查(if(user.role==='admin')
)或更复杂的内容组成(参见示例)securedulote
组件,该组件是Route
的包装器,但会获取user
和permission
参数,并在用户看不到此路由时重定向checkUserPermission
函数有条件地呈现链接或组件//src/utils/checkUserPermission.js
导出默认函数checkUserPermission(用户={roles:[]},权限){
const AllowAccess for角色={
“route.admin”:[“admin”],
“路由.已验证”:[“用户”,“管理员”],
“route.home”:[“*”],//表示“任何角色”
“component.Authenticate”:[“*”、“!user”、“!admin”]、//除user和admin之外的任何角色
“component.BecomeAdmin”:[“用户”],
“组件.注销”:[“用户”,“管理员”]
};
//若我们在列表中并没有这样的权限,每个人都会被拒绝访问
if(!Array.isArray(allowAccessForRoles[permission])){
返回false;
}
//检查是否有任何用户角色明确拒绝访问
for(user.roles的常量角色){
if(AllowAccess角色[权限]。包括(“!”+角色)){
返回false;
}
}
//如果允许的角色列表包含“*”,则允许每个人访问
if(AllowAccess角色[权限]。包括(“*”){
返回true;
}
//检查是否有任何用户角色允许访问
for(user.roles的常量角色){
if(AllowAccess角色[权限]。包括(角色)){
返回true;
}
}
返回false;
}
//src/securedroote
从“React”导入React;
从“react router dom”导入{Route,Redirect};
从“/utils/checkUserPermission”导入checkUserPermission;
常数securedroote=({
用户,
许可,
重定向至=“/”,
儿童
休息
}) => {
const allowed=checkUserPermission(用户,权限);
如果(允许){
返回子项}/>;
}
返回(
(
)}
/>
);
};
导出默认值;
//src/App.js
从“React”导入React,{useState};
导入“/styles.css”;
从“react Router dom”导入{BrowserRouter as Router,Switch,Link};
从“/securedroote”导入securedroote;
从“/utils/checkUserPermission”导入checkUserPermission;
const AdminPage=()=>管理员页面为管理员打开;
const AuthenticatedPage=()=>(
已为用户和管理员打开验证页面
);
const HomePage=()=>主页对所有人开放;
导出默认函数App(){
const[user,setUser]=useState();
返回(
转到主页
{checkUserPermission(用户,“route.authenticated”)(
转到已验证页面
):null}
{checkUserPermission(用户,“route.admin”)(
转到管理页面
):null}
{checkUserPermission(用户,“component.Authenticate”)(
setUser({角色:[“用户”]})}>
认证
):null}
{checkUserPermission(用户,“component.BecomeAdmin”)(
setUser({roles:[“admin”]})}>
成为管理员
):null}
{checkUserPermission(用户,“component.LogOut”)(
setUser()}>
注销
):null}
);
}
我可以使用令牌控制用户是否登录,如果用户登录则渲染组件,问题是如何控制reactjs上的用户是否登录以及该用户具有哪个角色(“管理员”或“简单用户”)。如果要了解用户具有什么角色,只需让后端将该数据与token@besartm可以那么,当恶意用户手动将其角色设置为“a”时会发生什么情况
const App = () => {
const isLoggedIn = true;
return (
<Router>
<Switch>
<ProtectedRoute showRoute={isLoggedIn} path="/dashboard" component={LoggedInDashboard} />
<Route path="/dashboard" component={LoggedOutDashboard} />
</Switch>
</Router>
);
}
const userLogin = React.createContext(false);
const LoggedInRoute = (props) => {
const showRoute = useContext(userLogin);
if (showRoute) {
return <Route {...props} />
} else {
return null;
}
}
const App = () => {
const [userLoggedIn, setUserLoggedIn] = React.useState(false);
return (
<userLogin.Provider value={userLoggedIn}>
<Router>
<LoggedInRoute path="/dashboard" component={Users} />
</Router>
</userLogin.Provider>
);
}
//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>
);
}