javascript - 如何动态使用react路由
问题描述
我有一个应用程序,其中我有两个登录名,一个superAdmin
用于“管理员”,另一个用于“管理员”。
我有几个页面一个是常见的(主页),两个用户都有多余的。
然后我还有其他几个页面,有些是 for
admin
,有些是 forsuperAdmin
。现在,当我打开我的页面时,我正试图走“/”这条路线(我的家路线)。 我想要做什么
现在,如果我以管理员身份登录并且管理员用户
superAdmin
在地址栏中输入一些 url,我希望将其重定向到当前的管理员路由同样
superAdmin
适用两个用户我都想限制多余的彼此路线
如果我是管理员用户或超级管理员用户并尝试登录并尝试过多的经过身份验证的路由,我应该重定向到主页
我做了什么
我在这里创建了一个组件(动态路由),我正在检查用户正在尝试做什么。在我的路由文件中的 route.js 中,我将道具传递为guest
,superAdmin
和admin
动态路由.js 代码
我已经创建了我的上下文来存储用户登录后
export default function Dynamicroute(props) {
const { user } = useAuthState(); // this I am getting from my context
console.log(user);
if (props.partner && !user) {
console.log('admin not logedin');
return <Redirect to="/admin" />;
} else if (props.admin && !user) {
console.log('superAdmin not loged in');
return <Redirect to="/superAdmin" />;
} else if (props.admin && user.role === 'admin') {
console.log('admin logedin');
return <Redirect to="/admin_home" />;
} else if (props.admin && user.role === 'superAdmin') {
console.log('super admin loged in');
return <Redirect to="/superadmin_home" />;
} else if (props.guest && user) {
console.log('guest');
return <Redirect to="/" />;
} else {
return <Route component={props.component} {...props} />;
}
}
我的 route.js
<DuynamicRoute exact path="/" component={Home} guest />
<DuynamicRoute path="/admin" component={loginAdmin} guest />
<DuynamicRoute path="/superAdmin" component={loginSuperAdmin} guest />
<DuynamicRoute path="/admin_home" component={admin_home} admin/>
<DuynamicRoute path="/superAdmin_home" component={superAdmin_home} superAdmin/>
我面临的问题
我不知道我面临的问题是在登录时将我重定向到该路由但内容未加载如果我在该页面上控制台某些内容我无法获得该页面,则该页面将变为空白。
已编辑
请检查这个
编辑
admin 和 super admin 将在不同的浏览器中登录,所以只是不希望 admin 访问 super admin,反之亦然,如果他们输入 url
解决方案
为了更好地管理和开发程序以及最佳实践,在 React.js 中进行授权,如下所示:
首先:您需要一个class
检查permissions
,routes/pages configs
如下所示:
class AppUtils {
static setRoutes(config) {
let routes = [...config.routes];
if (config.auth) {
routes = routes.map((route) => {
let auth = config.auth ? [...config.auth] : null;
auth = route.auth ? [...auth, ...route.auth] : auth;
return {
...route,
auth
};
});
}
return [...routes];
}
static generateRoutesFromConfigs(configs) {
let allRoutes = [];
configs.forEach((config) => {
allRoutes = [...allRoutes, ...this.setRoutes(config)];
});
return allRoutes;
}
static hasPermission(authArr, userRole) {
/**
* If auth array is not defined
* Pass and allow
*/
if (authArr === null || authArr === undefined) {
// console.info("auth is null || undefined:", authArr);
return true;
} else if (authArr.length === 0) {
/**
* if auth array is empty means,
* allow only user role is guest (null or empty[])
*/
// console.info("auth is empty[]:", authArr);
return !userRole || userRole.length === 0;
} else {
/**
* Check if user has grants
*/
// console.info("auth arr:", authArr);
/*
Check if user role is array,
*/
if (userRole && Array.isArray(userRole)) {
return authArr.some((r) => userRole.indexOf(r) >= 0);
}
/*
Check if user role is string,
*/
return authArr.includes(userRole);
}
}
}
export default AppUtils;
第二:您需要授权组件来处理如下路由:
import React, { Component } from "react";
import AppUtils from "utils/AppUtils";
import { matchRoutes } from "react-router-config";
import { withRouter } from "react-router-dom";
import AppContext from "context/AppContext";
class AppAuthorization extends Component {
constructor(props, context) {
super(props);
const { routes } = context;
this.state = {
accessGranted: true,
routes
};
}
componentDidMount() {
if (!this.state.accessGranted) {
this.redirectRoute();
}
}
componentDidUpdate() {
if (!this.state.accessGranted) {
this.redirectRoute();
}
}
static getDerivedStateFromProps(props, state) {
const { location, userRole } = props;
const { pathname } = location;
const matched = matchRoutes(state.routes, pathname)[0];
return {
accessGranted: matched
? AppUtils.hasPermission(matched.route.auth, userRole)
: true
};
}
shouldComponentUpdate(nextProps, nextState) {
return nextState.accessGranted !== this.state.accessGranted;
}
redirectRoute() {
const { location, userRole, history } = this.props;
const { pathname, state } = location;
const redirectUrl = state && state.redirectUrl ? state.redirectUrl : "/";
/*
User is guest
Redirect to Login Page
*/
if (!userRole || userRole.length === 0) {
history.push({
pathname: "/login",
state: { redirectUrl: pathname }
});
} else {
/*
User is member
User must be on unAuthorized page or just logged in
Redirect to dashboard or redirectUrl
*/
history.push({
pathname: redirectUrl
});
}
}
render() {
// console.info('App Authorization rendered', accessGranted);
return this.state.accessGranted ? (
<React.Fragment>{this.props.children}</React.Fragment>
) : null;
}
}
// AppAuthorization.defaultProps = {
// userRole: [] // You can manage roles by redux or any state managements
// };
AppAuthorization.contextType = AppContext;
export default withRouter(AppAuthorization);
第三:您需要 authRoles 文件或远程来管理客户端上的角色,如下所示:
/**
* Authorization Roles
*/
const authRoles = {
admin: ["admin"],
superAdmin: ["superAdmin"],
user: ["user"],
onlyGuest: []
};
export default authRoles;
第四:如果你想继续这个逻辑,你必须实现你的页面结构如下:
src
|---pages
|---home
|---HomePage.jsx
|---HomePageConfig.jsx
|
|- The rest of the pages should be implemented in the same way
例如:当你想实现一个只有管理员才能看到的页面时(管理员主页配置):
import React from "react";
import authRoles from "auth/authRoles";
export const AdminHomePageConfig = {
auth: authRoles.admin,
routes: [
{
path: "/admin",
exact: true,
component: React.lazy(() => import("./HomePage"))
}
]
};
或者大家都能看到的首页:
import React from "react";
export const HomePageConfig = {
routes: [
{
path: "/",
exact: true,
component: React.lazy(() => import("./HomePage"))
}
]
};
根据上面的例子,你可以auth prop
在这里输入with role
,来限制对页面的访问。
为了更深入地了解这个逻辑,我在 Codesandbox 中实现了它,您可以通过以下链接查看:
注意:上面的demo需要更完善一些,并且不要在状态中存储用户角色,最好使用状态管理包(redux,...),也可以通过cookies进行登录操作。
推荐阅读
- r - 如何使用模型名称和变量列表来计算带有预测的表?
- android - 将 byte[ ] 转换为 String 返回 <���� 在 android bluetooth low energy 上工作
- laravel - 在 Laravel 中创建模型会导致数据库错误
- mysql - 如何在mysql中进行查询计算
- c# - 电子邮件发送期间读取值错误之前的 EWS 加载属性
- javascript - 反应日期选择器返回无效日期
- reactjs - 反应:即使没有状态,我可以/应该使用自定义钩子而不是 HOC 吗?
- swift - 如何快速连接蓝牙设备?
- angular - 错误:找不到带有路径的控件:“技能 -> 熟练度”
- apache - 重定向,除非 URL 以特定字符串开头