reactjs - 使用 React-router-dom 和 Redux useSelector hook 保护路由
问题描述
我正在尝试保护我的一些路线,因为您必须经过身份验证才能定向到该路线。我将我的路由包装在一个执行一些验证的 routerWrapper 函数中,然后在验证后它重定向到正确的路由。我正在使用 useSelector 检查我的 authState,然后如果路由 isPrivate 和 isAuthenticated 我重定向到该路由,但毫无疑问地在第一个 React 渲染时我得到 isAuthenticated 为假,因此该函数正在返回登录路由。这是我的代码
const RouteWrapper = ({component, isPrivate, ...props}: IRoutProps) => {
//Add another property to check isAdmin
const state = useSelector((state: AppState) => state.auth);
const {isAuthenticated} = state;
console.log(isAuthenticated);
if (isPrivate) {
if (!state.isAuthenticated) {
console.log('Private');
return <Redirect to="/login" />;
} else {
return <Route {...props} component={component} />;
}
} else {
if (
props.path === '/login' &&
state.isAuthenticated === true &&
(state.user.type === 'Instructor' || state.user.type === 'Student')
) {
return <Redirect to="/" />;
} else if (
props.path === '/admin/login' &&
state.isAuthenticated &&
state.user.type === 'Admin'
) {
return <Redirect to="/admin/dashboard" />;
}
return <Route {...props} component={component} />;
}
};
解决方案
解决此问题的一种方法是status
在您的状态中添加类似的内容。现在,此状态可能是以下状态之一idle
(初始化时)、fetching
(仍在确定用户是否已通过身份验证时)和processed
(已完成身份验证,现在我们知道结果)。
您需要在代码的不同部分设置不同的状态。例如,在您设置的地方isAuthenticated
,您需要在设置fetching
之前将您的状态设置为isAuthenticated
,一旦解决,您需要将您的状态设置为processed
。
这样我们就知道一旦状态变为processed
,我们就会得到我们的isAuthenticated
值,然后我们就可以继续我们的逻辑了。
如果我们继续将状态添加到您的状态,那么我们可以将我们的代码修改为类似这样
const RouteWrapper = ({component, isPrivate, ...props}: IRoutProps) => {
const state = useSelector((state: AppState) => state.auth);
const {isAuthenticated, status, user} = state;
if (status === 'processed') {
if (isPrivate) {
return isAuthenticated ?
(<Route {...props} component={component} />) :
(<Redirect to="/login" />)
} else {
if (
props.path === '/login' &&
isAuthenticated &&
(user.type === 'Instructor' || user.type === 'Student')
) {
return <Redirect to="/" />;
} else if (
props.path === '/admin/login' &&
isAuthenticated &&
user.type === 'Admin'
) {
return <Redirect to="/admin/dashboard" />;
}
return <Route {...props} component={component} />;
}
}
};
这应该避免在确定用户是否通过身份验证之前isAuthenticated
初始化组件时首次渲染组件。false
推荐阅读
- mongodb - MongoDB.service 失败,结果退出代码
- python - 比较 PCAP 数据集
- raku - 如何在使用 NativeCall 的 Raku 发行版中捆绑 C 源代码?
- firebase - StreamBuild:流,调用返回Firestore的方法 Stream在更新之前不会检索数据
- angular - 带字体模块的角度
- snowflake-cloud-data-platform - 雪花存储过程。JavaScript 内存不足错误
- scala - Scala Builder递归的对象
- laravel - Laravel,在刀片视图中使用 groupBy
- python - 无法从 PostGresSQL 表中获取行
- angular - 如何手动触发关闭 ng-bootstrap 弹出框