如何在 React/Redux 应用程序中刷新页面后保持登录状态

bil*_*lal 1 javascript reactjs react-router redux react-redux

我正在使用 redux 状态保护路由。我在做什么是当用户的loggedIn我更新Redux的状态isAuthenticatedsignIn组件和接受我的这种状态AllRoutes的组件,然后我在定制的路由传递它ProtectedHomeRoute作为道具。一切正常,但问题是当我刷新时,我得到的isAuthenticatedfalse是它的默认值,因此,ProtectedHomeRoute将我重定向到Login页面。

请建议我在上述用例中处理浏览器刷新的最佳方法

我试图以这种方式解决这个问题,我做了一个名为isLoggedInthis 我正在调用 API 来检查登录状态的新动作,如果响应是那么我在有效负载中传递 true

然后我在componentDidMount生命周期中调用此操作,AllRoutes 以便在浏览器刷新时isLoggedIn将被调用并且无法获得以前的状态,但事情不会以这种方式发生。

这是isLoggedIn行动代码

export function isLoggedIn() {
  axios.get("http://localhost:8080/api/checkLoginStatus").then(res => {
    let data = res.data; 
    let tid = data.data; // data contain userId
    console.log(tid);
    let isAuthenticate =  false
    if(tid){
      isAuthenticate = true;
    }  
    return dispatch => {
      dispatch({
        type: "isLoggedIn",
        payload: isAuthenticate
      });
    };
  })
}
Run Code Online (Sandbox Code Playgroud)

这是 auth Reducer 代码

    const INITIAL_STATE = {
    isAuthenticate: false
  };

  export default (states = INITIAL_STATE, action) => {
    switch (action.type) {
      case "loggedIn":
        return {
          ...states,
          isAuthenticate: action.payload
        };
      case "logOut":
        return {
          ...states,
          isAuthenticate: action.payload
        };
        case "isLoggedIn":
        return {
          ...states,
          isAuthenticate: action.payload
        };

      default:
        return states;
    }
  };
Run Code Online (Sandbox Code Playgroud)

AllRouts 组件代码

import { isLoggedIn } from "./store/action/authAction";
import axios from 'axios';

class AllRoutes extends React.Component {

  componentDidMount() {
    isLoggedIn();
  }
  render() {
    console.log(this.props.isAuthenticate);

    return (
      <Router>        
        <Switch>
          <Route path="/auth/signup" component={Signup} />
          <Route path="/auth/signin" component={Signin} />
          <Route path="/auth/forgot" component={Forgot} />
          <Route exact path="/stock" component={Products} />
          <Route exact path="/stock/detail/:id" component={Manage} />
          <ProtectedHomeRoute
            exact
            path="/"
            component={<Home />}
            isAuthenticate={this.props.isAuthenticate}
          />
        </Switch>
      </Router>
    );
  }
}

// to access redux stats as props in this component
function mapStateToProps(state) {
  return {
    isAuthenticate: state.authReducer.isAuthenticate
  };
}

function mapDispatchToProps(dispatch) {
  return {
    userAuthenticate: a => {
      dispatch(isLoggedIn(a));
    }
  };
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(AllRoutes);

// protected route for Home component
const ProtectedHomeRoute = ({ component, isAuthenticate, ...rest }) => {
  console.log("protected route", isAuthenticate);
  return (
    <Route
      {...rest}
      render={props =>
        isAuthenticate ? component : <Redirect to="/auth/signin" />
      }
    />
  );
};
Run Code Online (Sandbox Code Playgroud)

小智 5

根据您的代码,我猜测您更像是一名前端开发人员。您不应该使用 userId 进行身份验证。你必须在后端使用类似 jwt 的东西。使用 jwt,您可以为每个登录用户创建一个令牌。将令牌保存在 LocalStorage 中,并将其作为标头与每个请求一起传递,并使您的私有路由需要该令牌。您可以阅读 jwt 文档,这应该能让您了解它的外观:

身份验证操作 身份验证操作

认证减速器 认证减速器

私人路线 私人路线