首页 > 解决方案 > 认证后加载用户的问题

问题描述

我在加载经过身份验证的(登录)用户时遇到问题,我使用 jwt 进行身份验证(使用 localStorage 存储令牌)......一旦用户成功登录,他被重定向到主页,这工作正常但是当我重新加载页面时重定向到登录页面......但所需的功能是,如果他重新加载验证他不应该重定向登录,它应该重新加载主页直到用户点击注销......这是我的代码......我不知道我哪里出错了...

这是登录功能

 const loginUser = async (userInfo) => {
setLoading();
const config = {
  headers: {
    "Content-Type": "application/json",
  },
};
try {
  const res = await axios.post("/api/auth", userInfo, config);
  console.log(res.data);
  dispatch({ type: LOGIN_SUCCESS, payload: res.data });
  loadAuthenticatedUser();
} catch (err) {
  console.log(err.response.data.errors);
  dispatch({ type: LOGIN_FAIL, payload: err.response.data });
}

};

这是loadAuthenticatedUser函数:我在主页组件中调用了这个函数,你可以看到上面的loginUser函数我在成功req后调用了它......

const loadAuthenticatedUser = async () => {
setLoading();
//set global header to check token exist if exist setToken
if (localStorage.token) {
  setToken(localStorage.token);
}
try {
  const res = await axios.get("/api/auth");
  console.log(res);
  dispatch({ type: LOAD_AUTHENTICATED_USER, payload: res.data });
} catch (err) {
  console.log(err.response.data);
  dispatch({ type: LOAD_AUTH_ERROR, payload: err.response.data });
}

};

这是 authReducer

case LOGIN_SUCCESS:
  localStorage.setItem("token", action.payload.token);
  return {
    ...state,
    isAuthenticate: true,
    loading_State: false,
    user_State: action.payload.token,
  };

case LOAD_AUTHENTICATED_USER:
  return {
    ...state,
    isAuthenticate: true,
    loading_State: false,
    user_State: action.payload,
  };
case REGISTER_FAIL:
case LOGIN_FAIL:
case LOAD_AUTH_ERROR:
  localStorage.removeItem("token");
  return {
    ...state,
    error_State: action.payload.errors,
    isAuthenticate: false,
    loading_State: false,
    token_State: null,
    user_State: null,
  };

case LOGOUT:
  localStorage.removeItem("token");
  return {
    ...state,
    isAuthenticate: false,
    loading_State: false,
    token_State: null,
    user_State: null,
  };

case CLEAR_AUTH_ERRORS:
  return {
    ...state,
    error_State: null,
    user_State: null,
    loading_State: false,
  };
case SET_LOADING:
  return {
    ...state,
    loading_State: true,
  };

default:
  return {
    ...state,
  };

}

导出默认的 AuthReducer;

在主页组件中:

useEffect(() => {
if (isAuthenticate && !loading_State) {
  loadAuthenticatedUser();
}
clearAuthErrors();
// eslint-disable-next-line

}, [isAuthenticate, loading_State]);

这是我的 app.js 文件渲染:

 return (
<AuthState>
  <ProfileState>
    <PostState>
      <AlertState>
        <Router>
          <Fragment>
            <Navbar />
            <Switch>
              <PrivateRoute Route exact path="/" component={Home} />

              <PrivateRoute
                Route
                exact
                path="/profile"
                component={UserProfile}
              />
              <Route exact path="/signup" component={SignUp} />
              <Route exact path="/signin" component={SignIn} />
            </Switch>
          </Fragment>
        </Router>
      </AlertState>
    </PostState>
  </ProfileState>
</AuthState>

);

这是经过身份验证后重定向的私有路由

return (
<Route
  {...rest}
  render={(props) =>
    !isAuthenticate && !loading_State ? (
      <Redirect to="/signin" />
    ) : (
      <Component {...props} />
    )
  }
/>

);

这是我登录后的初始状态在此处输入图像描述(使用反应开发工具):

当我重新加载时,isAuthenticate 值设置为 false ,但是在 authReducer 中你可以看到我将它设置为 true 以防 LOAD_AUTHENTICATED_USER ...我在主页和 authState 中调用了一个函数,当成功登录时...但是它是不应用...这是状态,如果我在主页时重新加载

在此处输入图像描述

标签: reactjs

解决方案


在浏览器刷新时,除非显式持久化,否则您的应用程序状态(组件状态和 redux 存储)将完全重置:所有变量内容都将被删除。
在您的情况下,您应该确保 PrivateRoute 在刚刚重置状态时不会重定向。为此,您应该初始化loading_State为 true。


推荐阅读