【问题标题】:ReactJS: Unable to create Protect route for private screenReactJS:无法为私有屏幕创建保护路由
【发布时间】:2021-10-03 22:28:35
【问题描述】:

客户端(React)我有一个受保护的路由,只有在用户登录时才能访问。

后端(Node.js,Express)中,我使用 JWT 并将其存储在 cookie 中 - 访问令牌和刷新令牌以对用户进行身份验证。访问令牌每 30 秒过期一次,刷新令牌用于重新创建访问令牌。

我要做的是为登录用户创建一个受保护的路由,通过检查accesToken cookie和refreshtoken cookie是否存在,以下是代码:

Auth.js

import axios from "axios";
import Cookies from "universal-cookie";
const cookies = new Cookies();

axios.defaults.withCredentials = true;
class Auth {
  constructor() {
    this.authenticated = false;
  }

  isAuthenticated() {
    const accessToken = cookies.get("authSession");
    const refreshToken = cookies.get("refreshTokenID");

    if (!accessToken && !refreshToken) {
      return (this.authenticated = false);
    }

    if (accessToken && refreshToken) {
      return (this.authenticated = true);
    }

    if (!accessToken && refreshToken) {
      axios
        .post("/api/auth/refresh", {
          withCredentials: true,
        })
        .then(function (res) {
          console.log(res.data);
          // window.location.reload();
        })
        .catch(function (error) {
          console.log(error.response);
        });
    }
  }
}

export default new Auth();

ProtectedRoutes.js

import { Route, Redirect } from "react-router-dom";
import Auth from "./Auth";

const ProtectedRoutes = ({ component: Component, ...rest }) => {
  console.log("????", Auth.isAuthenticated());

  return (
    <Route
      {...rest}
      render={(props) =>
        Auth.isAuthenticated() ? (
          <Component {...props} />
        ) : (
          <Redirect to="/loginRegister" />
        )
      }
    />
  );
};

export default ProtectedRoutes;

一切正常,我可以登录,cookie 会过期并在每 30 秒后重新创建。除非访问令牌过期并重新创建,否则Auth.isAuthenticated() 返回undefined。它仅在前 30 秒内返回 true(即仅在第一个访问 cookie 未过期之前),但是当我尝试刷新我的私人页面时,它会返回到 loginRegister 页面

cookies 也存在:

更新

我忘记添加我的 loginHandler 和 Privatescreen Route:

路线

import React from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import LoginRegisterScreen from "../../screens/LoginRegisterScreen/LoginRegisterScreen";
import ProtectedRoutes from "../Protect/ProtectedRoutes";
import PrivateScreen from "../../screens/PrivateScreen/PrivateScreen";

const Body = () => {
  return (
    <Router>
      <Switch>
        <ProtectedRoutes exact path="/" component={PrivateScreen} />
        <Route exact path="/loginRegister" component={LoginRegisterScreen} />

      </Switch>
    </Router>
  );
};

export default Body;

loginHandler 在我的 loginRegisterScreen.js

const loginHandler = async (e) => {
    e.preventDefault();
    console.log("Login hander called");

    const config = {
      headers: {
        "Content-Type": "application/json",
      },
    };

    try {
      await axios.post(
        "/api/auth/login",
        {
          email: loginEmail,
          password: loginPassword,
        },
        config
      );
      history.push("/");
    } catch (error) {
      setLoginError(error.response.data.error);
      setTimeout(() => {
        setLoginError("");
      }, 5000);
    }
  };

更新 2

事实证明我仍然登录,如果我在浏览器中手动输入我的私人 URL(即http://localhost:3000/),它允许我访问它,只是,每当我的 cookie 过期时,Auth.isAuthenticated() 得到@987654342 @ 我被推回/loginRegister 路线。我应该怎么做才能使它成为true 而不是undefined

更新 3

添加图片以便更好地理解:

  1. 登录后,我的保护路线立即进入阳离子并打开私人屏幕。

  2. 在我的访问令牌过期 30 秒后,如果我刷新页面,我会推回到 /loginRegister 路由,因为它在 Auth.isAuthenticated() 未定义。

  3. 只有当我再次手动输入 URL 并输入时,它才会转到私有路由:

更新 4

得到未定义的错误

【问题讨论】:

    标签: javascript reactjs react-router jwt


    【解决方案1】:

    在 Auth.js 中,您在声明新的 accessToken 后不会返回任何内容。您可以像下面那样在此处返回 true;

    ...
     if (!accessToken && refreshToken) {
          axios
            .post("/api/auth/refresh", {
              withCredentials: true,
            })
            .then(function (res) {
              console.log(res.data);
              return (this.authenticated = true); // <-- this is a new piece of code here
              // window.location.reload();
            })
            .catch(function (error) {
              console.log(error.response);
            });
        }
    

    【讨论】:

    • 感谢回复,我试过return (this.authenticated = true),但我不知道为什么它仍然显示undefined,只有当我手动输入URL时,它才会返回return (this.authenticated = true)。我已经用图片更新了问题,以便更好地了解正在发生的事情。
    • 我认为你需要调试isAuthenticated。如果它仍然未定义,则要么进入 catch 块,要么不满足任何 if 条件,isAuthentucated 在不返回任何内容时未定义
    • @AnkushDogra,而不是console.log(error.response);,你可以在caatch 块中记录console.log(error); 吗?
    • 登录后我得到TypeError: this is undefined,你说得对,它会被阻塞,
    猜你喜欢
    • 2021-02-13
    • 1970-01-01
    • 2019-08-13
    • 1970-01-01
    • 2020-07-23
    • 1970-01-01
    • 2019-08-31
    • 1970-01-01
    • 2021-04-30
    相关资源
    最近更新 更多