Next.js中间件未传递服务器返回Cookie问题排查
问题原因与解决方法
核心原因
Next.js 中间件运行在Edge Runtime(服务器端/Edge节点),而非用户浏览器环境,所以客户端浏览器中保存的 Cookie 不会自动被中间件内的 fetch 请求携带。另外还有两个常见配置问题会导致 Cookie 无法传递:
- Django 端的 Cookie 属性(SameSite、Domain、Secure)配置不符合跨域/跨子域场景要求
- Django 的 CORS 配置未正确开启凭证支持
解决步骤
1. 修改中间件代码,手动转发 Cookie
中间件可以从请求头中获取客户端传来的 Cookie,然后手动添加到 fetch 请求头里,替换原来的 credentials: "include" 配置:
export default async function middleware(request) { // 检查是否访问受保护路由 if (PROTECTED_ROUTES.includes(request.nextUrl.pathname)) { try { // 从请求头中获取客户端的 Cookie const clientCookie = request.headers.get('cookie'); let res = await fetch( `${process.env.NEXT_PUBLIC_BACKEND_URL}/authentication/check`, { headers: { // 如果存在 Cookie,就添加到请求头 ...(clientCookie && { Cookie: clientCookie }), }, } ); // 未登录则重定向到登录页 if (res.status !== 200) { return NextResponse.redirect(new URL(PAGE_ROUTES.LOGIN, request.url)); } } catch (error) { return NextResponse.redirect(new URL(PAGE_ROUTES.LOGIN, request.url)); } } }
2. 检查并修正 Django 的 Cookie 配置
在 Django 的 settings.py 中,确保 Cookie 的属性设置符合场景:
# 设置 Cookie 的 SameSite 属性,跨域场景用 Lax 或 None(None 需要配合 Secure) SESSION_COOKIE_SAMESITE = 'Lax' # 跨域时如果是 HTTPS 可以设为 'None' SESSION_COOKIE_SECURE = True # HTTPS 环境下必须开启,否则 SameSite=None 不生效 # 如果是跨子域场景,设置父域名,比如 Next.js 是 app.example.com,Django 是 api.example.com SESSION_COOKIE_DOMAIN = '.example.com'
- 如果 Next.js 和 Django 是完全不同的顶级域名,SameSite 需设为
None,同时必须开启Secure(仅 HTTPS 环境可用) - Domain 属性要覆盖 Next.js 和 Django 的域名,确保 Cookie 能在两者间共享
3. 确保 Django 的 CORS 配置支持凭证
在 Django 的 settings.py 中开启 CORS 凭证支持,并添加允许的 Origin:
CORS_ALLOW_CREDENTIALS = True CORS_ALLOWED_ORIGINS = [ "https://your-nextjs-domain.com", # 替换成你的 Next.js 域名 ]
这样修改后,中间件就能正确携带客户端的 Cookie 去请求 Django 的验证接口,不会再被错误重定向到登录页。
内容的提问来源于stack exchange,提问作者U. Watt
相关产品推荐
相关产品推荐

