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

跨域生产环境下Next.js中间件无法读取JWT Cookie问题

跨域场景下Next.js中间件无法读取Cookie的解决方案

问题背景

我开发的应用前端基于Next.js,后端采用Node.js+Express.js架构,通过Next.js中间件实现JWT鉴权。本地开发阶段,前后端运行在localhost不同端口(前端http://localhost:3000、后端http://localhost:8001),所有功能正常。但部署到生产环境后,前端域名是https://frontend.com,后端域名是https://backend.com:8001,此时Next.js中间件无法读取Cookie中的JWT令牌,导致鉴权授权功能失效。

相关代码

Next.js 中间件代码

// next.js middleware
import { NextResponse } from "next/server";
import { jwtVerify } from "jose";
// ... 其他导入 ...

const secret = process.env.SECRET;

async function verify(token, secret) {
    const { payload } = await jwtVerify(token, new TextEncoder().encode(secret));
    return payload;
}

export default async function middleware(request) {
    const url = request.url;
    const nextUrl = request.nextUrl.clone();
    // ... 中间件其他逻辑 ...

    // 权限校验示例函数
    const checkAccess = async (allowedRole) => {
        const jwt = request.cookies.get('token')?.value;
        if (!jwt) {
            nextUrl.pathname = '/';
            return NextResponse.rewrite(nextUrl);
        }
        
        try {
            const verification = await verify(jwt, secret);
            if (verification.Role === allowedRole) {
                return NextResponse.next();
            } else {
                throw new Error("ACCESS DENIED");
            }
        } catch (e) {
            // 错误处理
            // ...
        }
    };

    // 角色校验
    if (url.includes("/dashboard/teacher")) {
        return checkAccess('Teacher');
    }
    // ... 其他校验逻辑 ...
    return NextResponse.next();
};

后端登录接口的Cookie配置

function getDomainURL(){
    switch (process.env.NODE_ENV){
        case ('production'):
            return '.frontend.com';
        case ('development'):
            return 'localhost'
    }
}

const COOKIE_OPTIONS = {
    httpOnly: true,
    path: "/",
    sameSite: 'None', // 允许跨域请求携带Cookie
    secure: true, // sameSite为None时必须设置为true
    domain: getDomainURL()
};

res.setHeader("Set-Cookie", serialize("token", token, COOKIE_OPTIONS));

function getOriginURL(){
    switch (process.env.NODE_ENV){
        case ('production'):
            return 'https://www.frontend.com';
        case ('development'):
            return 'http://localhost:3000'
    }
}

let originURL = getOriginURL()

app.use(cors({
    origin: originURL,
    credentials: true,
}))

解决步骤

1. 修正Cookie的Domain配置

生产环境中,后端设置的Cookie domain为.frontend.com,需确保前端域名frontend.com和www.frontend.com都能匹配该Cookie:

  • 现代浏览器中顶级域名前缀的点(.)可选,但为兼容老版本浏览器可保留
  • 确认后端设置的domain与前端实际域名完全匹配,避免因www前缀导致的Cookie无法读取

2. 强制前端请求携带Credentials

前端调用后端登录接口时,必须显式设置credentials: 'include',确保浏览器在跨域请求中携带Cookie:

// 前端登录请求示例
fetch('/api/login', {
    method: 'POST',
    credentials: 'include', // 关键配置
    body: JSON.stringify(loginData)
})

3. 配置Next.js跨域代理

在Next.js项目的next.config.js中添加路由重写规则,将前端API请求转发到后端,避免直接跨域请求:

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
    async rewrites() {
        return [
            {
                source: '/api/:path*',
                destination: 'https://backend.com:8001/api/:path*',
            },
        ]
    },
}

module.exports = nextConfig

配置后前端请求/api/login会被转发到后端对应接口,此时请求属于同域(前端域名),Cookie会被正常携带,Next.js中间件即可读取。

4. 校验SameSite与Secure属性

  • 生产环境下sameSite: 'None'必须配合secure: true,且必须使用HTTPS协议,否则浏览器会拒绝存储Cookie
  • 本地开发阶段若使用HTTP,需将secure设为false,sameSite设为Lax或Strict,避免浏览器阻止Cookie

5. 确认Cookie作用域

确保Cookie的path设置为"/",保证前端域名下所有路径都能访问该Cookie。

验证方法

  1. 登录后,在浏览器开发者工具的Application > Cookies > https://frontend.com中查看是否存在token Cookie
  2. 访问需要鉴权的路由(如/dashboard/teacher),在Next.js中间件中打印request.cookies,确认能获取到token值

内容的提问来源于stack exchange,提问作者Joaquín Caballero

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 09:18:36