我正在寻找一种有效的方法来防止未经授权的人员访问特定的路由路径。
我从后端获取的cookie不可读,因此我无法做很多事情。我有两个端点:
我到目前为止所做的简短说明:
我的问题:
[如果我关闭我的标签并打开一个新标签,则商店将重置(正常且正常)。该cookie仍然可用。因此,对于一个好的UX,我想直接对用户进行身份验证。目前,用户已重定向到登录页面。这是有道理的,因为只有在store属性isAuthenticated为true时,才能访问PrivateRoute组件。因此,用户必须再次登录才能更新商店。
我试图通过方法componentDidMount在App.js中调度一个操作,以直接获取用户凭据,但这没有帮助。由于render()首先被触发,因此无济于事。
这是我的代码:
App.js:
export class App extends PureComponent {
componentDidMount() {
// Action to retrieve user credentials (if available then saves it to the authStore and sets isAuthenticated to true)
this.props.initloginRequest();
}
render() {
return (
<div className="d-flex flex-column h-100 w-100 bg-grey main-container">
<Sprites className="d-none" />
<Router>
<Header />
<Switch>
<Route path="/login" exact component={X1} />
<PrivateRoute path="/" exact component={X2} />
<PrivateRoute path="/details" exact component={X3} />
<PrivateRoute path="/finish" exact component={X4} />
</Switch>
</Router>
</div>
);
}
}
export class PrivateRoute extends Component {
render() {
const { isAuthenticated, component, ...rest } = this.props;
const renderComponent = (props) => {
if (isAuthenticated) {
const ComponentToShow = component;
return <ComponentToShow {...props} />
} else {
return <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
}
};
return (
<Route
{...rest}
render={renderComponent}
/>
)
}
}
export default connect(
(state) => ({
isAuthenticated: state.authStore.isAuthenticated
})
)(PrivateRoute);
为此,有一个可能的解决方案,即根据返回的状态代码对/ account进行api调用。每当路线改变时,都会拨打电话,这并不是我真正想要的。我只想要一个在应用程序开始时需要一个调用的解决方案。
提前感谢
我已经通过在index.js(src路径)中调度一个动作解决了这个问题:
import './index.css';
import App from './App';
import { initloginRequest } from './actions/auth';
const store = configureStore();
store.dispatch(initloginRequest())
ReactDOM.render(
<Provider store={store}>
<ConnectedRouter history={history}>
<App />
</ConnectedRouter>
</Provider>,
document.getElementById('root'),
);
此操作将调用api并检查用户是否已通过身份验证。因此,当到达我的PrivateRoute组件时,它知道应该以哪个方向重定向用户。
您应该在商店/状态中将isFetching设置为true,直到操作完成,以防止App.js呈现您的路线。
export class App extends PureComponent {
render() {
const { isFetching } = this.props
if (isFetching) {
return <div>Loading application...</div>
}
return (
<div className="d-flex flex-column h-100 w-100 bg-grey main-container">
<Sprites className="d-none" />
<Header />
<Switch>
...private route etc...
</Switch>
</div>
);
}
}
export default connect(
(state) => ({
isFetching: state.authStore.isFetching,
}),
(dispatch) => bindActionCreators({
}, dispatch),
)(App);
这应该可以解决问题。