reactjs挂钩中的页面刷新时丢失身份验证状态

时间:2020-01-03 06:45:57

标签: reactjs react-hooks

当我使用有效凭据服务器登录时,将JWT发送到浏览器,然后将此JWT存储在localstore页面中,重定向到首页,一切正常,在首页中,我具有loadUser函数,该函数将请求发送到服务器以获取有效用户的用户详细信息,但是当我刷新页面时,它的主页永远不会执行,因为身份验证状态返回false并将页面从主页重定向到登录页面 这是App.js

 import React, { Fragment } from "react";
        import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
         import Navbar from "./components/layout/Navbar";
       import Home from "./components/pages/Home";
        import Login from "./components/auth/Login";
        import PrivateRoute from "./components/routing/PrivateRoute";
      import "./App.css";
       const App = () => {
      return (
            <AuthState>
              <Router>
            <Fragment>
              <Navbar />
              <div className="container">
                <Alerts />
                <Switch>
                  <PrivateRoute exact path="/" component={Home} />
                  <Route exact path="/login" component={Login} />
                </Switch>
              </div>
            </Fragment>
          </Router>
         </AuthState>
  );
};
export default App;
这是我的验证码,成功登录后,状态会从这里更改

import React, { useReducer } from "react";
    import axios from "axios";
    import AuthContext from "./authContext";
    import authReducer from "./authReducer";
    import {
      USER_LOADED,
      AUTH_ERROR,
      LOGIN_SUCCESS,
      LOGIN_FAIL,
      } from "../types";
    const AuthState = props => {
      const initialState = {
          isAuthenticated: null,
          user: null,
      };
      const [state, dispatch] = useReducer(authReducer, initialState);
      // Load User
      const loadUser = async () => {
        if (localStorage.token) {
          setAuthToken(localStorage.token);
        }
        try {
          const res = await axios.get("/api/auth");
          dispatch({ type: USER_LOADED, payload: res.data });
        } catch (err) {
          dispatch({ type: AUTH_ERROR });
        }
      };
      // Login User
      const login = async formData => {
        const config = {
          headers: {
            "Content-Type": "application/json"
          }
        };
        try {
          const res = await axios.post("api/auth", formData, config);
          dispatch({
            type: LOGIN_SUCCESS,
            payload: res.data
          });
          loadUser();
        } catch (err) {
          dispatch({
            type: LOGIN_FAIL,
            payload: err.response.data.msg
          });
        }
      };
      return (
        <AuthContext.Provider
          value={{
                  isAuthenticated: state.isAuthenticated,
              user: state.user,
              loadUser,
            login,
         }}
        >
          {props.children}
        </AuthContext.Provider>
      );
    };
    export default AuthState;

这是化简代码authReducer.js

import {
  USER_LOADED,
  AUTH_ERROR,
  LOGIN_SUCCESS,
  LOGIN_FAIL,
    } from "../types";
   export default (state, action) => {
  switch (action.type) {
    case USER_LOADED:
      return {
        ...state,
        isAuthenticated: true,

        user: action.payload
      };
       case LOGIN_SUCCESS:
      localStorage.setItem("token", action.payload.token);
      return {
        ...state,
          isAuthenticated: true
         };
       case AUTH_ERROR:
    case LOGIN_FAIL:
         localStorage.removeItem("token");
      return {
        ...state,

        isAuthenticated: false,
           user: null,
         };
         default:
      return state;
  }
};

This is private route
import React, { useContext } from "react";
import { Route, Redirect } from "react-router-dom";
import AuthContext from "../../context/auth/authContext";

const PrivateRoute = ({ component: Component, ...rest }) => {
  const authContext = useContext(AuthContext);
  const { isAuthenticated, loading } = authContext;
  return (
    <Route
      {...rest}
      render={props =>
        !isAuthenticated && !loading ? (
          <Redirect to="/login" />
        ) : (
          <Component {...props} />
        )
      }
    />
  );
};

export default PrivateRoute;

2 个答案:

答案 0 :(得分:1)

可能是用于用户身份验证/授权的JSON Web令牌。您能给我们更多信息吗?

答案 1 :(得分:1)

这是意料之中的。

如果您要保留令牌,则应将其保存在localStoragecookie中。

然后,如果您使用的是componentDidMount,则应在useEffecthooks(带有无效依赖项数组)中检查令牌的存在和有效性。

如果您可以告诉我们您在哪里发出AJAX请求,那就太好了,因为例如,如果您使用的是Axios,则可以将此逻辑封装在request拦截器中