如何在Next.js服务端API调用外部API时移除Cookie?
你遇到的核心问题有两个:一是客户端浏览器不允许手动修改Cookie请求头(这是浏览器的安全限制,所以你看到了Refused to set unsafe header "Cookie"的报错);二是你用的rewrites配置会自动将客户端请求的所有头信息(包括Cookie)转发给外部API,没办法直接过滤。
要解决这个问题,你需要放弃rewrites,改用自定义Next.js API路由来处理代理逻辑——这样你就能在服务端完全控制发送给外部API的请求头,彻底移除Cookie。
具体实现步骤
1. 创建自定义API路由
在pages/api/proxy/目录下创建[...path].ts文件(这个通配符路由会匹配所有/api/proxy/*的请求),在里面用Axios调用外部API,并且明确不传递Cookie:
// pages/api/proxy/[...path].ts import axios from 'axios'; import type { NextApiRequest, NextApiResponse } from 'next'; export default async function handler(req: NextApiRequest, res: NextApiResponse) { try { // 从通配符参数中提取外部API的路径 const { path } = req.query; const externalUrl = `${process.env.EXTERNAL_API_GATEWAY_URL}/${Array.isArray(path) ? path.join('/') : path}`; // 手动构造请求头,只保留需要的字段,刻意排除Cookie const headers: Record<string, string | undefined> = { 'Content-Type': req.headers['content-type'] as string, 'Authorization': req.headers['authorization'] as string, // 可根据需求添加其他必要头信息,比如Accept、X-Request-ID等 }; // 调用外部API,严格控制Cookie传递 const response = await axios({ method: req.method, url: externalUrl, headers, data: req.body, // 转发POST/PUT等请求的请求体 params: req.query, // 转发查询参数(若有) // 关键配置:禁用自动携带Cookie withCredentials: false, }); // 将外部API的响应原样返回给客户端 res.status(response.status).json(response.data); } catch (error) { // 错误处理逻辑 if (axios.isAxiosError(error)) { res.status(error.response?.status || 500).json(error.response?.data || { message: 'Proxy request failed' }); } else { res.status(500).json({ message: 'Unexpected error occurred' }); } } }
2. 修改客户端的queryData函数
现在你不需要在客户端设置Cookie头了,直接调用API路由即可,服务端会自动处理Cookie的移除:
export const queryData = (caller: string, enabled = true) => { return useQuery( ['queryData ', caller], async () => { const { data } = await httpClient.get('/api/proxy/getData'); // 移除无效的headers配置,交由服务端代理逻辑处理 return data; }, { ...useQueryOptions, enabled } ); };
3. 更新next.config.js
移除之前的rewrites配置,因为自定义API路由已经接管了/api/proxy/*的请求:
module.exports = (phase) => { return { // 移除原有rewrites配置 } };
为什么这个方案有效?
- 所有代理逻辑在Next.js服务端运行,不受浏览器安全限制,你可以完全控制请求头的内容。
- 通过
withCredentials: false(Axios的核心配置)确保不会携带任何Cookie到外部API,同时手动构造请求头,只保留业务需要的字段,彻底排除Cookie。 - 客户端请求逻辑几乎不需要修改,保持原有调用方式即可。
额外注意事项
- 若外部API需要特定头信息,请在API路由的
headers对象中添加对应字段。 - 可将外部API网关地址存入环境变量(比如
process.env.EXTERNAL_API_GATEWAY_URL),方便不同部署环境切换。 - 如果需要转发部分Cookie而非全部,可以在API路由中手动筛选
req.headers.cookie里的字段,只保留需要的内容再传递给外部API。
内容的提问来源于stack exchange,提问作者Kim Gentes
相关产品推荐
相关产品推荐

