我试图在我的应用程序中实现一些安全性并最终创建以下代码:
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
const PrivateRoute = ({
component: Component,
auth: { isAuthenticated, loading },
...rest
}) => (
<Route
{...rest}
render={props =>
!isAuthenticated && !loading ? (
<Redirect to='/auth/login' />
) : (
<Component {...props} />
)
}
/>
);
PrivateRoute.propTypes = {
auth: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth
});
export default connect(mapStateToProps)(PrivateRoute);
auth
来自我的状态管理,从Chrome浏览器上安装的Redux Devtools进行查看时,状态管理看起来完全像这样;在这里:
isAuthenticated
和loading
通常在用户登录时为true;效果很好。我遇到的问题是,没有人登录时,我的PrivateRoute不会重定向到auth/login
页。有谁知道如何解决这个问题?这是我的一条需要PrivateRoute组件的路线的示例:
<PrivateRoute exact path='/edit-basics' component={EditBasics} />
上面的路线是一个页面,用于编辑仅对他/她可用的当前已登录用户信息。我仍然没有登录就可以访问它。
答案 0 :(得分:0)
似乎您没有将auth传递给PrivateRoute。尝试添加它。
<PrivateRoute exact path='/edit-basics' component={EditBasics} auth={this.props.auth}/>
答案 1 :(得分:0)
也许是这样
const PrivateRoute = ({ component,
auth: { isAuthenticated, loading },
...options }) => {
let history = useHistory();
useLayoutEffect(() => {
if ( !isAuthenticated && !loading) history.push('/auth/login')
}, [])
return <Route {...options} component={component} />;
};
答案 2 :(得分:0)
因此,将&&
运算符和要传递给render
的{{1}}方法的三元运算中的两个表达式可能会出错。
您将必须找到另一种方式来验证它是否仍在加载。
在JSX中,如果您将Route
与true && expression
配对,那么基本上您将返回expression
作为要渲染的组件。
了解更多:https://reactjs.org/docs/conditional-rendering.html#inline-if-with-logical--operator
!loading
另外,
React Router的作者建议使用子组件构造这种专用路由,而不是将组件传递为道具。
了解更多:https://reacttraining.com/react-router/web/example/auth-workflow
const PrivateRoute = ({
component: Component,
auth: { isAuthenticated, loading },
...rest
}) => (
<Route
{...rest}
render={props =>
// TWO OPERATIONS WITH && WILL CAUSE ERROR
!isAuthenticated && !loading ? (
<Redirect to='/auth/login' />
) : (
<Component {...props} />
)
}
/>
);
并拨打该路线:
function PrivateRoute({ auth, children, ...rest }) {
return (
<Route
{...rest}
render={() =>
!auth.isAuthenticated ? (
<Redirect
to={{
pathname: "/auth/login",
state: { from: location }
}}
/>
) : (
children
)
}
/>
);
}