You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 12 API路由中无法获取Cookie的问题求助

问题原因

当你在getServerSideProps中用fetch调用内部API路由时,这个请求是服务器端发起的,默认不会携带客户端浏览器的Cookie。而直接访问API路由时,请求来自浏览器,浏览器会自动带上当前域名下的Cookie,所以后端能正常获取。

解决方案

有两种可行的处理方式,根据你的需求选择:

方案1:直接在getServerSideProps中查询数据库(推荐)

既然getServerSideProps本身就在服务器端运行,没必要多一次内部API请求,直接在这里验证Cookie并查询用户的任务:

// src/pages/tasks/index.js
import mongoose from 'mongoose';
import Task from '../../models/Task'; // 你的Task模型
import { jwtVerify } from "jose";

export async function getServerSideProps(context) {
  // 从context中获取客户端的Cookie
  const { userAuthToken } = context.req.cookies;

  if (!userAuthToken) {
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      },
    };
  }

  try {
    // 验证JWT
    const { payload } = await jwtVerify(userAuthToken, new TextEncoder().encode("secret"));
    
    // 连接数据库(如果还没连接)
    if (!mongoose.connections[0].readyState) {
      await mongoose.connect(process.env.MONGODB_URI);
    }

    // 查询当前用户的任务
    const tasks = await Task.find({ userId: payload.userId });

    return {
      props: { tasks: JSON.parse(JSON.stringify(tasks)) } // 转换为可序列化的JSON
    };
  } catch (error) {
    console.error(error);
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      },
    };
  }
}

方案2:手动传递Cookie到fetch请求

如果你坚持要通过API路由获取数据,需要把getServerSideProps中拿到的Cookie手动添加到fetch的请求头里:

// src/pages/tasks/index.js
export async function getServerSideProps(context) {
  const URL = process.env.NEXT_PUBLIC_TASKS_API_URL;
  // 从context.req中获取客户端的Cookie
  const cookies = context.req.headers.cookie;

  const response = await fetch(URL, {
    headers: {
      // 把Cookie传递给API路由
      Cookie: cookies || ''
    }
  });

  const tasks = await response.json();

  return {
    props: {
      tasks: tasks.error ? [] : tasks
    }
  };
}

同时,确保你的API路由能正确解析Cookie(Next.js 12中req.cookies是自动解析的,只要请求头里有Cookie就可以拿到):

// src/pages/api/tasks/index.js
export default async function handler(req, res) {
  const { method, cookies } = req;
  const { userAuthToken } = cookies;

  if (!userAuthToken) {
    return res.status(401).json({ error: '未授权' });
  }

  // 后续验证JWT、查询数据库逻辑...
}
额外提示
  • 不要在JWT中存储密码!JWT是可明文解码的,存储密码会导致安全问题,只需要存用户ID、用户名这类非敏感信息即可。
  • 中间件已经在做身份验证,getServerSideProps或API路由里的验证可以作为二次校验,确保安全性。

内容的提问来源于stack exchange,提问作者Genaro Bonavita

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 14:10:28