next.js 尝试刷新axios拦截器中的令牌之前,应用程序中弹出Axios错误401消息

bzzcjhmw  于 2023-01-25  发布在  iOS
关注(0)|答案(1)|浏览(145)

AxiosConfig.js

import axios from "axios";
import { store } from "./redux/store";
import { login, logout } from "./redux/slices/user";

const baseURL = process.env.NEXT_PUBLIC_API_URL;

axios.defaults.baseURL = baseURL;

export const axiosInstance = axios.create({
  withCredentials: true,
  headers: {
    "Content-Type": "application/json",
    "Access-Control-Allow-Origin": "*",
    accept: "application/json",
  },
});

axiosInstance.interceptors.request.use(
  (config) => {
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

axiosInstance.interceptors.response.use(
  (response) => {
    return response;
  },
  async (error) => {
    const originalRequest = error?.config;
    if (error?.response?.status === 401 && !originalRequest.sent) {
      originalRequest.sent = true;
      const response = await axios.get("/auth/refresh", {
        withCredentials: true,
      });
      if (response.error.status === 403) {
        store.dispatch(logout());
      }
      store.dispatch(login({ user: response.data.user }));
      return axiosInstance(originalRequest);
    }
    return Promise.reject(error);
  }
);

VerifyJwt.js

export const verifyToken = (req, res, next) => {
  try {
    const accessToken = req.cookies.accessToken;
    if (!accessToken)
      return res.status(403).json({
        message: "Not authenticated, no token provided",
      });
    jwt.verify(accessToken, process.env.ACCESS_SECRET_KEY, (err, decoded) => {
      if (err)
        return res.status(401).json({
          message: "Not logged in, invalid token",
        });
      req.user = decoded.id;
      next();
    });
  } catch (e) {
    res
      .status(500)
      .json({ message: "Something went wrong while verifying jwt" });
  }
};

routes/video.js

import express from "express";
import { unAuthVerify, verifyToken } from "../middlewares/verifyJwt.js";
import {
  deleteVideo,
  dislikeVideo,
  getVideoDetails,
  getVideos,
  likeVideo,
  updateVideo,
  uploadVideo,
} from "../controllers/videos.js";

const router = express.Router();
router.get("/", getVideos);
router.post("/", verifyToken, uploadVideo);
router.get("/:id", unAuthVerify, getVideoDetails);
router.put("/:id", verifyToken, updateVideo);
router.delete("/:id", verifyToken, deleteVideo);
router.put("/like/:id", verifyToken, likeVideo);
router.put("/dislike/:id", verifyToken, dislikeVideo);

export default router;

RefreshToken.js

export const refreshToken = async (req, res) => {
  const refreshToken = req.cookies.refreshToken;
  try {
    if (refreshToken) {
      jwt.verify(
        refreshToken,
        process.env.REFRESH_SECRET_KEY,
        async (err, decoded) => {
          if (err) {
            return res.status(403).json({
              message: "Invalid token/not logged in",
            });
          }
          const accessToken = jwt.sign(
            { id: decoded.id },
            process.env.ACCESS_SECRET_KEY,
            {
              expiresIn: "1m",
            }
          );
          const foundUser = await db.query(
            "SELECT * FROM channels WHERE id = $1",
            [decoded.id]
          );
          if (foundUser.rows.length <= 0) {
            return res.status(400).json({
              message: "User/Channel not found",
            });
          }
          const { password, ...others } = foundUser.rows[0];
          if (foundUser.rows.length > 0) {
            res.cookie("accessToken", accessToken, {
              httpOnly: true,
              secure: true,
            });
            return res.status(200).json({
              user: others,
            });
          }
        }
      );
    } else {
      return res.status(403).json({
        message: "Invalid token/not logged in",
      });
    }
  } catch (e) {
    console.log(e);
    res.status(500).json({
      message: "Something went wrong.Please try again",
    });
  }
};

Video.jsx

const handleLike = async (id) => {
   if (!isLoggedIn) {
     toast.error("You need to login to like a video");
     return;
   }
   if (likedByMe) {
     toast.success("You have already liked this video");
     return;
   }

   try {
     await axiosInstance.put(`/videos/like/${id}`);
     setLikes((prev) => prev + 1);
     if (likedByMe === false) {
       setDisLikes((prev) => prev - 1);
     }
     setLikedByMe(true);
   } catch (e) {
     console.log("Something went wrong while liking video", e);
     toast.error(e.response.data.message);  //I am getting this error first and the app is 
   crashing and only then axios interceptors call refresh token endpoint)
   }
 };

我正在尝试刷新axios拦截器中的令牌并获取新的访问令牌。例如,假设我尝试不喜欢或喜欢任何视频,并且我的访问令牌在那时到期,我将收到令牌已过期的401消息,但我认为在客户端收到此响应之前(在catch块中发生),axios拦截器将调用刷新令牌,因为它是404消息,客户端将获得新的访问令牌,然后不喜欢或喜欢的API请求将再次发生。但在我的应用程序中,我收到该错误消息,它使应用程序崩溃,axios拦截器不应该静默处理吗?客户端的catch块捕获了404非法消息,并弹出错误

uajslkp6

uajslkp61#

我注意到您的路由名为video.js,但您发送了一个PUT请求到videos/(复数)。这是打印错误,还是问题的原因?

相关问题