JWT 令牌过期不会使用户返回/登录页面

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

我正在开发一个 PERN 项目,使用 JWT 令牌进行授权。目前,我遇到了这样的问题,即具有过期 JWT 令牌的用户将停留在同一页面上,并显示一条 toast 错误消息,指出“授权中的错误:令牌已过期”。

我希望我的用户被重定向到 /partner/login,并清除本地存储并在检测到过期令牌时显示 toast 消息。

但是,就我而言,FE 知道 JWT 令牌已经过期,因为打印了 console.log('expiredddddd') 但序列行无法正常工作,因为未显示 toast 消息,localStorage 不清楚,用户未重定向到

/partner/login
。用户必须刷新手动页面才能重定向到
/partner/login
。有谁可以帮忙看看这个问题吗?

import React, { useEffect } from "react";
import { Navigate, Outlet } from "react-router-dom";
import Spinner from "../utils/Spinner";
import toast from "react-hot-toast";
import { jwtDecode } from "jwt-decode";

const AuthenticatedRoute = ({
  isAuthenticated,
  loading,
  isLoggingOut, // New prop to indicate if the user is logging out
}) => {
  const token = localStorage.getItem("token");

  useEffect(() => {
    // Check if token exists and is not expired
    if (token) {
      const decodedToken = jwtDecode(token);
      const currentTime = Date.now() / 1000; // Convert milliseconds to seconds
      if (decodedToken.exp < currentTime) {
        // Token expired
        console.log("expiredddddd"); // this was printed but sequence lines got ignored 
        toast.error("Your session has expired. Please log in again.");
        localStorage.clear(); // Remove expired token
        return <Navigate to="/partner/login" />;
      }
    }
  }, [token]);

  // Check if there is no token and the user is not authenticated
  if (!token && !isAuthenticated && !isLoggingOut) {
    toast.error("You have not logged in");
    return <Navigate to="/partner/login" />;
  }

  // Check if the user is not authenticated and loading is complete
  if (!isAuthenticated && !loading && !isLoggingOut) {
    toast.error("You have not logged in");
    return <Navigate to="/partner/login" />;
  }

  // Show loading spinner while authentication status is being determined
  if (loading) {
    return <Spinner />;
  }

  // Render the child routes if the user is authenticated
  return <Outlet />;
};

export default AuthenticatedRoute;

这是我的中间件

const jwt = require("jsonwebtoken");
require("dotenv").config();

module.exports = async (req, res, next) => {
  // get token and method from header
  const authHeader = req.headers.authorization;
  if (authHeader) {
    // Split the authorization header into parts
    const parts = authHeader.split(" ");
    if (parts.length === 2 && parts[0] === "Bearer") {
      const jwtToken = parts[1]; // Extract the token from the header
      try {
        const payload = jwt.verify(jwtToken, process.env.jwtSecret);
        req.user = payload.user; // Attach user data to request object

        next();
      } catch (err) {
        if (err instanceof jwt.TokenExpiredError) { 
          return res
            .status(401)
            .json({ error: "ERROR in Authorization: Token expired" }); 
                   // I was able to see this message
        } else if (err instanceof jwt.JsonWebTokenError)
          return res
            .status(401)
            .json({ error: "ERROR in Authorization: Invalid JWT" });
        return res
          .status(500)
          .json({ error: "ERROR in Authorization: Server error" });
      }
    } else {
      // Invalid authorization header format
      return res.status(401).json({ error: "Invalid authorization header" });
    }
  } else {
    // Authorization header not present
   return res.status(401).json({ error: "Authorization header missing" });
  }
};
reactjs node.js express jwt
1个回答
0
投票

您无法通过返回

useEffect()
中的组件来直接操作渲染。

相反,请尝试在

isExpired
中设置状态
useEffect()
,然后在
useEffect()
之外设置状态
<Navigate to="/partner/login" />
(如果
isExpired
为 true)。

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