React JS 中的专用路由 jsx

Private Route jsx in react JS

问题:我正在尝试通过 isAuth() 助手对用户进行身份验证,但它表现得很奇怪。我希望它查找访问令牌(如果有的话),或者如果刷新令牌可用则从后端调用访问令牌,虽然它工作正常并设置访问令牌 cookie,但问题是如果从 PrivateRoutes.jsx 调用,它看不到令牌并将用户发送到登录页面。

为参考添加所需的代码:

isAuth():

export const isAuth = () => {
  if (window !== undefined) {
    const accessCookieChecked = getCookie("_mar_accounts_at");
    const refreshCookieChecked = getCookie("_mar_accounts_rt");
    if (accessCookieChecked) {
      return true;
    } else if (refreshCookieChecked) {
      console.log(refreshCookieChecked);
      axios({
        method: "POST",
        url: `${API_URL}/api/token`,
        data: { refresh_token: refreshCookieChecked },
      }).then((res) => {
        console.log(res);
        setCookie("_mar_accounts_at", res.data.accessToken);
        return true;
      });
    } else {
      return false;
    }
  } else {
    return false;
  }
};

PrivateRoutes.jsx

import React from "react";
import { Route, Redirect } from "react-router-dom";

import { isAuth } from "../helpers/auth";

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route
    {...rest}
    render={(props) =>
      isAuth() ? (
        <Component {...props} />
      ) : (
        <Redirect
          to={{ pathname: "/login", state: { from: props.location } }}
        />
      )
    }
  ></Route>
);

export default PrivateRoute;

有人可以看看这个吗?并帮助!

您很可能 运行 陷入异步问题,当您在 axios 中进行调用时,回调中的 return true; 实际上从未 returns 到您在 PrivateRoute 中的函数调用.相反,您需要使用 Promise/setState/useEffect:

export const isAuth = () => {
  if (window === undefined) {
    return Promise.resolve(false);
  } else {
    const accessCookieChecked = getCookie("_mar_accounts_at");
    const refreshCookieChecked = getCookie("_mar_accounts_rt");
    if (accessCookieChecked) {
      return Promise.resolve(true);
    } else if (refreshCookieChecked) {
      console.log(refreshCookieChecked);
      return new Promise(resolve => {
        axios({
          method: "POST",
          url: `${API_URL}/api/token`,
          data: { refresh_token: refreshCookieChecked },
        }).then((res) => {
          console.log(res);
          setCookie("_mar_accounts_at", res.data.accessToken);
          resolve(true);
        });
      })
      
    } else {
      return Promise.resolve(false);
    }
  }
};
import React, { useState, useEffect } from 'react';
import { Route, Redirect } from 'react-router-dom';

import { isAuth } from '../helpers/auth';

const PrivateRoute = ({ component: Component, ...rest }) => {
  const [isAuthTrue, setIsAuthTrue] = useState();
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    isAuth().then(res => {
      setIsAuthTrue(res);
      setLoading(false);
    })
  })
  return (
    <>
      {loading ? (
        <div>some loading state</div>
      ) : (
        <Route
          {...rest}
          render={(props) =>
            isAuthTrue ? (
              <Component {...props} />
            ) : (
              <Redirect
                to={{ pathname: '/login', state: { from: props.location } }}
              />
            )
          }
        />
      )}
    </>
  );
};
export default PrivateRoute;