我的应用程序中有这个流程。用户注册/登录,JWT保存在浏览器的存储器中。每当用户刷新页面时,如果存在JWT并且商店没有用户,则它向api发出请求并返回包含用户的json。
index.js
if (localStorage.websiteJWT) {
setAuthorizationHeader(localStorage.websiteJWT);
if(!store.getState().user.email)
store.dispatch(fetchCurrentUser());
}
现在我让用户出现在商店里。用户对象如下所示:
{user: {username: "Bob", admin: true}}
现在我有以下用户路线:
AdminRoute:
-
和将用于其他人的正常路线。
这是管理路线的样子:
<AdminRoute exact location={location} path='/admin/locations' component={LocationsPage}/>
现在我遇到以下情况:
1)管理员用户已经在网站上,商店已经拥有所需的状态state.user.admin
,并且他没有任何问题地转到localhost:3000/admin/locations
页面。
2)管理员用户直接从浏览器转到该页面,此时商店没有存在用户信息并开始获取它,但是当它返回时,重定向已经发生。在这种情况下,管理员用户永远不能访问管理面板。
我知道这是因为我可以在控制台中看到商店打印几次
Is user admin? undefined
和Is user admin? true
几次。
我该如何解决情况2?
我想到的唯一解决方案是将一个用户对象存储在localStorage中,就像令牌一样。它并不理想,因为它很容易绕过。即使它不能访问真实数据,因为令牌不是有效的,我也不喜欢这个选项。
编辑:我尝试实施评论中建议的解决方案。我确实有一个loaded: false
初始还原状态。
export default function user(state = { loaded: false }, action = {}) {
switch (action.type) {
case USER_LOGGED_IN:
return {...action.user, loaded: true};
case USER_FETCHED:
return {...state, ...action.user, loaded: true};
case USER_LOGGED_OUT:
return {};
case USER_CONFIRMED:
return {...state, confirmed: true};
default:
return state;
}
}
我相应地更改了我的AdminRoute:
const AdminRoute = ({ loaded, isAuthenticated, component: Component, ...rest }) => {
console.log(`Is user admin? ${isAuthenticated}`);
console.log(`Loaded? ${loaded}`);
return (
<Route
{...rest}
render={props =>
<div>
loaded && isAuthenticated &&
<div>
<AdminNavigation />
<Component {...props} />
</div>
loaded && !isAuthenticated && <Redirect to="/" />
</div>
}
/>
)
};
AdminRoute.propTypes = {
component: PropTypes.func.isRequired,
isAuthenticated: PropTypes.bool,
loaded: PropTypes.bool.isRequired
};
function mapStateToProps(state) {
return {
loaded: state.user.loaded,
isAuthenticated: state.user.admin
};
}
export default connect(mapStateToProps)(AdminRoute);
但是这行loaded && !isAuthenticated && <Redirect to="/" />
仍然在上面的行之前触发,我仍然被重定向。
我也得到了
Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.
我认为发生这种情况是因为它试图在LocationsPage
之后呈现Redirect
组件。