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

Express中已设置Cookie但req.cookies无法获取JWT的问题解决

问题:Express权限中间件无法获取JWT Cookie,导致验证失败

我使用Express作为后端、Next.js作为前端开发应用。登录后浏览器已成功设置名为jwt的Cookie,但在protect中间件中通过req.cookies?.jwt获取到的值为undefined,无法完成用户权限验证。相关代码如下:

相关代码

protect中间件

const protect = asyncHandler(async (req, res, next) => {
  let token;
  token=req.cookies?.jwt
  if (token) {
    try {
      const decoded = jwt.verify(token, process.env.JWT_SECRET);
      console.log(decoded)
      req.user = await prisma.user.findFirst({
        where: {
          email: decoded.email,
        },

      });
      next();
    } catch (err) {
      res.status(401);
      throw new Error(`Not Authorized, Invalid Token`);
    }
  } else {
    res.status(401);
    throw new Error(`Not Authorized, No Token`);
  }
});

generateToken函数

const generateToken = (res, email) => {
  console.log('email form generate',email)
  try {
    const token = jwt.sign({ email }, process.env.JWT_SECRET, {
      expiresIn: "30d",
    });
    console.log(token)
    res.cookie("jwt", token, {
      httpOnly: true,
      secure: process.env.NODE_ENV==="Production",
      sameSite: process.env.NODE_ENV==="Production"?"None":"Strict",
      maxAge: 30 * 24 * 60 * 60 * 1000,
    });
  } catch (error) {
    res.status(500);
    throw new Error(`Issue With Assiging JWT`);
  }
};

用户控制器

const loginUser = asyncHandler(async (req, res) => {
    const { email, password } = req.body;
    if (!email || !password) throw new Error(`Provide Valid User Details`);
    const validUser = await prisma.user.findFirst({
        where: {
           email:email,
        },

    });
    if (!validUser) throw new Error(`Invalid User Details`);
    const validPassword = await compareHashPassword(password, validUser.password);
    if (validUser && validPassword) {
      generateToken(res, validUser.email);
      const data = {
        email: validUser.email,
        isAdmin: validUser.isAdmin,
      };
      res.status(200).json({
        data,
        message: `Login Successfull`,
      });
    } else {
      res.status(400).send({message:"Invalid User Information"});
      throw new Error(`Invalid User Details`);
    }
  });
 

  const getUserProfile = asyncHandler(async (req, res) => {
    console.log('user',req.user)
   try{ 
    const data = {
      email: req.user.email,
        isAdmin: req.user.isAdmin,
    };
    res.status(200).json({ data });
  }catch(error){
    res.status(401).send({message:"UnAuthorized User"})
  }
  });

用户路由

// Login /api/users/signin
router.route("/signin").post(loginUser);

// Logout /api/users/logout
router.route("/logout").post(logoutUser);

//Get profile
router.get("/profile",protect, getUserProfile);

原因分析及修复方案

1. 未配置cookie-parser中间件

Express默认不会解析请求中的Cookie,必须通过cookie-parser中间件处理,否则req.cookies会是undefined。

修复:

  • 安装依赖:
npm install cookie-parser
  • 在Express入口文件(如server.js)中引入并启用:
const cookieParser = require('cookie-parser');

// 必须在路由配置之前添加
app.use(cookieParser());

2. 前端请求未携带Credentials

Next.js发送跨域请求时,默认不会携带Cookie,需显式开启credentials选项。

修复:

  • 使用fetch时:
fetch('/api/users/profile', {
  method: 'GET',
  credentials: 'include',
})
  • 使用axios时:
axios.get('/api/users/profile', {
  withCredentials: true,
})

3. SameSite配置不匹配开发环境

开发环境下sameSite设为Strict,若前后端运行在不同端口(如前端3000、后端5000),属于跨源请求,Strict会阻止Cookie携带。

修复:
修改generateToken中的SameSite配置,开发环境改为Lax:

res.cookie("jwt", token, {
  httpOnly: true,
  secure: process.env.NODE_ENV === "Production",
  sameSite: process.env.NODE_ENV === "Production" ? "None" : "Lax",
  maxAge: 30 * 24 * 60 * 60 * 1000,
});

注意:SameSite=None必须配合secure: true使用,而开发环境通常是HTTP协议,所以不能用None,否则浏览器会拒绝设置Cookie。

4. CORS未允许Credentials

前后端跨域时,Express需配置CORS允许携带Cookie。

修复:

  • 安装cors依赖:
npm install cors
  • 配置CORS:
const cors = require('cors');

app.use(cors({
  origin: process.env.FRONTEND_URL || 'http://localhost:3000', // 你的前端地址
  credentials: true,
}));

验证步骤

  1. 登录后,在浏览器开发者工具Application > Cookies中确认jwt Cookie存在,且Domain、Path配置正确。
  2. 发送/api/users/profile请求时,查看Network > 请求头是否包含Cookie: jwt=xxx。
  3. 在protect中间件开头添加console.log(req.cookies),确认是否能获取到Cookie对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 08:15:55