有没有一种方法可以将JWT令牌附加到NextJS应用程序路由器项目中的axios http请求

brjng4g3  于 2023-06-22  发布在  iOS
关注(0)|答案(1)|浏览(111)

我正在使用Next.js 13和应用路由器,并寻找一种方法来添加authorization header到axios http请求。
我用下面的方式创建了一个示例,代码期望从cookie中接收JWT令牌,但即使浏览器中设置了cookie,也没有定义。

import { getJWTCookie } from "@/utils/cookie";

import axios from "axios";

let cookie = getJWTCookie();

const userHTTP = axios.create({
  baseURL: process.env.NEXT_PUBLIC_API_URL,
  headers: {
    "Content-Type": "application/json",
  },
});

userHTTP.interceptors.request.use(
  (config) => {
    if (cookie) {
      config.headers["Authorization"] = `Bearer ${cookie}`;
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  },
);

export default userHTTP;

在控制台日志中,我得到的cookie如下:

'🚀 ~ cookie:',
  undefined
  '🚀 ~ cookie:',
  undefined
  '🚀 ~ cookie:',
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2NDhiMzMwYmMyZDU0YmU5OGY2ZjhlNjkiLCJ1c2VybmFtZSI6IkFha2FzaHgyODM4IiwiaWF0IjoxNjg2OTc1ODA0LCJleHAiOjE2ODk1Njc4MDR9.IsAtdoN7llMvQIQE_owHSE0f1FHP3vDN8RpgFP6yesE'

这是我如何设置和获取饼干。

export const getJWTCookie = () => {
  if (typeof window === "undefined") {
    return undefined;
  }

  if (!document.cookie) {
    return undefined;
  }

  const token = document.cookie
    .split("; ")
    .find((row) => row.startsWith(TOKEN_KEY))
    ?.split("=")[1];

  return token;
};

对API的调用是在如下所示的page.tsx文件中进行的

export default async function Cart() {
  const products = await getUserCart();
  console.log("🚀 ~ products:", products);
}

下面是getUserCart函数

import userHTTP from "@/lib/http";
import { AxiosResponse } from "axios";

export const getUserCart = async (): Promise<IUserCart[] | undefined> => {
  try {
    const res: AxiosResponse = await userHTTP({
      url: "/cart/me",
      method: "GET",
    });

    if (!res) return;

    return res.data;
  } catch (e) {
    console.log("🚀 ~ e:", e);
  }
};

然而,控制台日志中的响应抛出了401错误,当控制台在后端记录令牌时,我得到了undefined。
有没有什么方法可以让我在服务器端访问令牌(如果这就是导致这个问题的原因)

dl5txlt9

dl5txlt91#

// only server components can be `async`
export default async function Cart() {
  const products = await getUserCart();
  console.log("🚀 ~ products:", products);
}

你在服务器组件中调用getUserCart(),在服务器组件中调用userHTTP,它返回undefined。你应该为axios interceptor写一个钩子:

const useAxiosHook = () => {
  let cookie = getJWTCookie();

  const userHTTP = axios.create({
    baseURL: process.env.NEXT_PUBLIC_API_URL,
    headers: {
      "Content-Type": "application/json",
    },
  });

  useEffect(() => {
    const requestIntercept = userHTTP.interceptors.request.use(
      (config) => {
        if (cookie) {
          config.headers["Authorization"] = `Bearer ${cookie}`;
        }
        return config;
      },
      (error) => {
        return Promise.reject(error);
      }
    );
    // you could also have response interceptor here

    return () => {
      axiosAuth.interceptors.request.eject(requestIntercept);
    };
  }, [cookie]);

  return userHTTP;
};

export default useAxiosHook;

getUserCart中使用此钩子。

export const getUserCart = async (): Promise<IUserCart[] | undefined> => {
  try {
    const userHTTP=useAxiosHook()
    const res: AxiosResponse = await userHTTP({
      url: "/cart/me",
      method: "GET",
    });

    if (!res) return;

    return res.data;
  } catch (e) {
    console.log("🚀 ~ e:", e);
  }
};

然后将Cart组件转换为客户端组件

"use client";

export default async function Cart() {
  const products = await getUserCart();
  console.log("🚀 ~ products:", products);
}

相关问题