使用React,Redux和React Router处理身份验证

时间:2019-07-08 22:34:37

标签: javascript reactjs redux

我正在使用一个使用React,Redux和React Router的应用程序以及一个在Spring Boot中运行的API服务器。我有一个登录页面,在该页面上,当用户成功进行身份验证时,它将在本地存储中保存一个JWT,并调用一个将身份验证的redux状态设置为true的操作。每次有人进入页面时,我都想检查用户是否已通过身份验证,为此,我使用axios进行获取请求,并在服务器的标头中使用JWT,然后服务器向我回复用户信息(如果有效) JWT,或者如果它是无效的JWT,则显示“未认证”消息,如果此API调用的响应不同于“未认证”,则它将调用将身份验证状态设置为true的操作。

问题是,当我加载应用程序时,它的渲染速度比API调用快,因此它始终将我重定向到登录页面,因为渲染API时尚未准备好。 我已经解决了使用异步函数将所有RenderDOM.render函数包装在index.js中的问题,然后在API调用准备就绪时使用来加载页面。代码如下:

const user = async () => {
  const response = await Conexiones.get('/api/auth/isAuthenticated');
  if(response.data !== 'Not authenticated'){
    store.dispatch({type: AUTHENTICATED});
  }
}

user().then((response) => {
  ReactDOM.render(
    <Provider store={store}>
      <Router history={history}>
        <div>
          <Route exact path="/login" component={NotRequireAuth(Login)} />
          <Route exact path="/sign-in" component={NotRequireAuth(SignIn)} />
          <Route exact path="/forgot-password" component={NotRequireAuth(ForgotPassword)} />
          <Route exact path="/reset-password" component={NotRequireAuth(ResetPassword)} />
          <App />
        </div>
      </Router>
    </Provider>
    ,
    document.querySelector('#root')
  );
});

App组件内部,受保护的Route使用RequireAuth组件,如下所示:

export default function(ComposedComponent){
    class Authentication extends Component{
        componentWillMount(){
            if(!this.props.authenticated){
                history.push('/login');
            }
        }

        componentWillUpdate(nextProps){
            if(!nextProps.authenticated){
                history.push('/login');
            }
        }

        PropTypes = {
            router: PropTypes.object,
        }

        render(){
            return <ComposedComponent {...this.props}/>
        }
    }

    const mapStateToProps = (state) => {
        return {authenticated: state.auth.authenticated};
    }

    return connect(mapStateToProps)(Authentication);

}

我想知道这是否是一个好的解决方案,尤其是将ReactDOM.render方法包装在异步函数中的部分,或者是解决此问题的更好方法。

1 个答案:

答案 0 :(得分:0)

您可以在包装器中输入以下内容:

CHANGEDOCUMENT_READ_POSITIONS

}

这样,始终会呈现父组件,并且如果您的身份验证请求返回200,则会更新状态并呈现const Wrapper = () =>{ const [isAuthenticated, setAuthenticated] = useState(false) return !isAuthenticated ? <Login /> : <PrivateRoute /> 。当然,有更好的解决方案,但是要点是将api调用的结果绑定到state属性。或者:

PrivateRoute