【问题标题】:Client side authentication and protected routes using cookies in react在反应中使用 cookie 的客户端身份验证和受保护的路由
【发布时间】:2019-07-10 13:21:16
【问题描述】:

我目前在我的应用程序中使用无状态 JWT 令牌进行身份验证。在客户端,我正在运行一个具有受保护路由的 React + Redux 应用程序。它是使用 HOC 实现的,它检查 jwt 令牌是否存在并允许基于它的路由。

我最近读到 localstorage 不是存储 JWT 令牌的好地方。因此,我转而在 cookie 中使用 jwt。

但问题是如何在使用 cookie 时在客户端实现受保护的路由。 我在 react 应用程序中使用 react-router-dom 进行路由。

【问题讨论】:

  • 我认为您会使用 api 调用使用 cookie 来返回该用户的用户信息。该调用的结果将是更新的 redux 存储,这反过来将“保护”客户端路由。
  • 我确实考虑过这种方法。但是每次您访问受保护的路由时,HOC 都必须调用 api 进行检查,并且在请求解决之前存在延迟。我不想在每个页面加载之前都显示一个加载器。
  • @uman 您只能在安装应用程序时执行一次。对于所有受保护的路由,我相信您也在验证后端的 API 调用(例如,当您挂载受保护的组件时,您调用 API 以获取该屏幕的仅授权数据),因此每当您收到 Unauthorized响应,您始终可以将用户重定向到正确的位置,甚至在此重定向期间一起清除 redux 存储。

标签: reactjs cookies redux jwt react-router-v4


【解决方案1】:

简单,只要使用 if else

应用程序.js
import { connect } from "react-redux";
import { Redirect, Route, Switch } from "react-router";
import "./App.css";
import Auth from "./Components/Pages/Auth/Auth";
import Logout from "./Components/Pages/Auth/Logout/Logout";
import { checkAuthStatus } from "./Components/store/actions";

function App(props) {
  useEffect(() => {
    props.checkAuthStatus(); // checking authentication status of user on each reload
  }, []);

  // filtering routes based on the authentication state of user
  const getRoutes = () => {
    if (props.auth) {
      return <Switch>{/* ...authenticated routes */}</Switch>;
    } else {
      // unauthenticated routes
      return (
        <Switch>
          <Route path="/auth" component={Auth} />
          <Route path="/logout" component={Logout} />
          <Redirect to="/auth" />
        </Switch>
      );
    }
  };
  console.log(props.error);
  return (
    <div className="App">
      {
        <Suspense fallback={<div>loading...</div>}>
          {props.loading ? <div>Authenticating...</div> : getRoutes()}
        </Suspense>
      }
    </div>
  );
}

const mapStateToProps = (state) => {
  return {
    auth:
      state.login.data.token !== undefined && state.login.data.token !== null,
    loading: state.login.loading,
    error: state.login.error,
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    checkAuthStatus: () => dispatch(checkAuthStatus()),
  };
};

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

actions.js

import { axiosInstance } from "../../Utility/axiosInstance";
import { getCookie } from "../../Utility/cookies";
import * as actionTypes from "./actionTypes";

export const loginStart = () => {
  return {
    type: actionTypes.LOGIN_START,
  };
};
export const loginFailure = (error) => {
  return {
    type: actionTypes.LOGIN_FAILURE,
    error,
  };
};
export const loginSuccess = (data) => {
  return {
    type: actionTypes.LOGIN_SUCCESS,
    data,
  };
};

export const checkAuthStatus = () => {
  return (dispatch) => {
    dispatch(loginStart());
    let token = getCookie("token");
    axiosInstance
      .post("/checkauthstatus", { id: token })
      .then((res) => {
        console.log(res.data);
        dispatch(loginSuccess(res.data));
      })
      .catch((err) => {
        console.log(err);
        let error = "something went wrong";
        if (err.response) {
          error = err.response.message;
        }
        dispatch(loginFailure(error));
      });
  };
};

【讨论】:

    猜你喜欢
    • 2018-05-21
    • 2013-12-11
    • 2020-05-10
    • 2020-07-01
    • 2021-12-16
    • 1970-01-01
    • 2018-07-21
    • 2018-09-27
    • 1970-01-01
    相关资源
    最近更新 更多