React、Node.js、jwt 登录流程。我无法使用 accessToken 保持状态

问题描述 投票:0回答:1

我正在使用accessToken和refreshToken来登录过程。我决定使用httpOnly将accessToken存储在React useState中,将refreshToken存储在Cookie中。 accessToken保存在state中。 freshToken是保存的Cookie。当我登录页面时,我可以访问下一页,但是当我按 F5 时,我会返回登录页面。获取 accessToken 效果很好,但我不知道为什么该网站强迫我去登录网站。这是我的代码

const ProtectedRoute = ({ element, allowedRoles }) => {
  const { accessToken } = useContext(RoleContext);

  let role = "";

  if (accessToken !== "") {
    const decodedPayLoad = jwtDecode(accessToken);
    role = decodedPayLoad.role;
  }

  if (!accessToken) {
    return <Navigate to="/auth/login" replace />;
  }

  if (!allowedRoles.includes(role)) {
    return <Navigate to="/" replace />;
  }

  return element;
};

export default ProtectedRoute;
// Create an Axios instance
const axiosInstance = axios.create({
  baseURL: process.env.REACT_APP_API_BASE_URL || "http://localhost:3000", // Adjust the baseURL according to your backend API
  withCredentials: true,
});

// Axios request interceptor
axiosInstance.interceptors.request.use(
  (config) => {
    const accessToken = RoleContext.accessToken;
    if (accessToken) {
      config.headers["Authorization"] = `Bearer ${accessToken}`;
    }
    return config;
  },
  (error) => Promise.reject(error)
);


// Axios response interceptor
axiosInstance.interceptors.response.use(
  (response) => response,
  async (error) => {
    const {
      config,
      response: { status },
    } = error;
    const originalRequest = config;

    if (status === 401 && !originalRequest._retry) {
      originalRequest._retry = true;
      const { setAccessToken } = RoleContext;
      const navigate = useNavigate();

      try {
        const res = await axiosInstance.post("/auth/token");
        const newToken = res.data.accessToken;
        setAccessToken(newToken);
        axios.defaults.headers.common["Authorization"] = `Bearer ${newToken}`;
        originalRequest.headers["Authorization"] = `Bearer ${newToken}`;
        return axiosInstance(originalRequest);
      } catch (err) {
        navigate("/auth/login");
        return Promise.reject(err);
      }
    }
    return Promise.reject(error);
  }
);

export default axiosInstance;
const ProtectedRoute = ({ element, allowedRoles }) => {
  const { accessToken } = useContext(RoleContext);

  let role = "";

  if (accessToken !== "") {
    const decodedPayLoad = jwtDecode(accessToken);
    role = decodedPayLoad.role;
  }

  if (!accessToken) {
    return <Navigate to="/auth/login" replace />;
  }

  if (!allowedRoles.includes(role)) {
    return <Navigate to="/" replace />;
  }

  return element;
};

export default ProtectedRoute;
const root = ReactDOM.createRoot(document.getElementById("root"));

const AppRoutes = () => {


  const { accessToken } = useContext(RoleContext);
  let role = "";

  if (accessToken !== "") {
    const decodedPayLoad = jwtDecode(accessToken);
    role = decodedPayLoad.role;
  }

  const isAuthenticated = !!accessToken;

  console.log(isAuthenticated);

  return (
    <Routes>
      <Route
        path="/"
        element={
          <Navigate
            to={
              isAuthenticated
                ? role === "superadmin"
                  ? "/superadmin/index"
                  : role === "admin"
                  ? "/admin/index"
                  : "/user/index"
                : "/auth/login"
            }
            replace
          />
        }
      />
      <Route
        path="/superadmin/*"
        element={
          <ProtectedRoute
            element={<SuperAdminLayout />}
            allowedRoles={["superadmin"]}
          />
        }
      />
      <Route
        path="/admin/*"
        element={
          <ProtectedRoute
            element={<AdminLayout />}
            allowedRoles={["superadmin", "admin"]}
          />
        }
      />
      <Route
        path="/user/*"
        element={
          <ProtectedRoute
            element={<UserLayout />}
            allowedRoles={["superadmin", "admin", "user"]}
          />
        }
      />
      <Route path="/auth/*" element={<AuthLayout />}></Route>
    </Routes>
  );
};

root.render(
  <RoleProvider>
    <BrowserRouter>
      <AppRoutes />
    </BrowserRouter>
  </RoleProvider>
);

reactjs node.js express
1个回答
0
投票

如果您希望跨页面加载、刷新,甚至在 React 应用程序中的不同选项卡之间保留数据,那么仅依赖组件状态或上下文是不够的。

要有效维护访问令牌等数据,请考虑将其存储在 cookie 或本地存储中。这可以确保即使用户离开或刷新页面,数据仍然可以访问。

您可以创建自定义 React hook,以便在需要时从 cookie 中检索令牌。这种方法允许您在应用程序中轻松访问和使用令牌。

© www.soinside.com 2019 - 2024. All rights reserved.