Next.js服务端刷新Token后,后续Fetch请求未使用新Token问题
问题分析与解决方案
核心问题在于Next.js服务端的next/headers提供的cookies()是当前请求的静态快照,只会在请求初始化时读取一次,不会自动同步后续Cookie的变化。你的代码在第一次创建originalRequest时就把旧Cookie塞进了请求头,刷新Token后,旧请求对象里的Cookie值没有更新,导致重试请求依然使用过期Token。
解决步骤
1. 让_handleRequest每次都获取最新Cookie
修改_handleRequest方法,确保每次调用时都重新拉取最新的Cookie,而不是只在请求初始化时设置一次:
private _handleRequest = (req: RequestInit) => { if (!isBrowser()) { // 每次请求都重新获取最新的Cookie快照 const cookies = require('next/headers').cookies(); req.headers = { ...req.headers, // 保留原有其他头信息 Cookie: cookies.toString(), }; } };
2. 重试时更新请求头
在_handleError的重试逻辑中,不要直接复用旧的originalRequest,而是重新调用_handleRequest更新Cookie头:
protected async _handleError( err: any, originalRequest: RequestInit, url: string ) { if (err.status === 401) { try { const refreshResponse = await this.request(apis.authn.refreshAccessToken, {}); if (refreshResponse.success) { // 克隆原请求对象,避免修改原对象 const retryRequest = { ...originalRequest }; // 重新获取最新Cookie并更新请求头 this._handleRequest(retryRequest); return await fetch(`${this.baseURL}${url}`, retryRequest) .then(this._handleResponse) .then((originalResponse: any) => originalResponse.data); } } catch (error) { return Promise.reject(error); } } return Promise.reject(err); }
额外说明
- 服务端Fetch的
credentials: 'include'配置无效,因为服务端没有浏览器的Cookie存储机制,必须手动通过next/headers获取Cookie并设置到请求头。 - 确保刷新Token的接口正确设置了新的httpOnly Cookie,且Cookie的域名、路径等属性和原Token一致,避免Cookie无法被后续请求读取。
内容的提问来源于stack exchange,提问作者muzafako
相关产品推荐
相关产品推荐

