部署到Vercel的MERN应用JWT Token未存入Cookie问题求助
使用MERN(React+Express+MongoDB)栈开发的应用本地运行完全正常,但部署到Vercel后出现以下问题:
- JWT Token已正常生成,且能在响应头的
Set-Cookie字段中看到,但浏览器的Cookie存储中无该Cookie(开发者工具中无法找到) - 后续请求的JWT验证流程失败,返回未授权错误
报错截图
Vercel响应头截图

开发者工具报错截图


相关代码
index.js
const dotenv = require("dotenv"); const mongoose = require("mongoose"); const express = require("express"); const cors = require("cors"); const cookieParser = require("cookie-parser"); const jwt = require("jsonwebtoken"); const app = express(); //const configs = require("./config.js"); dotenv.config({ path: "./config.env" }); require("./db/connection"); //const config = configs[process.env.NODE_ENV || "development"]; app.use(express.json()); app.use(cookieParser()); // 使用CORS中间件允许特定来源的请求 app.use( cors({ origin: "https://frontEnd.vercel.app", // 替换为你的前端URL methods: "GET,HEAD,PUT,PATCH,POST,DELETE", credentials: true, // 允许请求携带Cookie和凭证 }) ); app.use(require("./router/route")); // 空中间件 const middleware = (req, res, next) => { next(); }; const PORT = process.env.PORT || 5000; app.listen(PORT, () => { console.log(`服务运行在端口 ${PORT}`); });
route.js
const express = require("express"); const bcrypt = require("bcrypt"); const router = express.Router(); require("../db/connection"); const User = require("../model/newUserSchema"); const Auth = require("../middleware/auth"); router.get("/", (req, res) => { res.send("后端服务已启动"); }); // 注册模块 router.post("/signup", async (req, res) => { const { username, email, cpassword, retypePassword } = req.body; if (!username || !email || !cpassword || !retypePassword) { return res.status(422).json({ error: "请填写完整信息" }); } try { const UserExist = await User.findOne({ email: email }); if (UserExist) { return res.status(422).json({ error: "该邮箱已注册" }); } else if (cpassword !== retypePassword) { return res.status(422).json({ error: "两次输入的密码不一致" }); } else { const user = new User({ username, email, cpassword, retypePassword, }); const userResgister = await user.save(); if (userResgister) { return res.status(201).json({ message: "注册成功" }); } } } catch (error) { console.log(error); } }); // 登录模块 router.post("/signin", async (req, res) => { try { const { email, cpassword } = req.body; if (!email || !cpassword) { return res.status(400).json({ error: "请输入完整登录凭证" }); } const userLogin = await User.findOne({ email: email }); if (userLogin) { const isMatch = await bcrypt.compare(cpassword, userLogin.cpassword); const token = await userLogin.generateAuthToken(); console.log("JWT Token: ", token); // 设置Cookie并指定正确的域名和路径(已注释) // res.cookie("signinToken", token, { // domain: "https://backend-api.vercel.app", // 设置域名以匹配前后端 // path: "/signin", // 设置Cookie生效路径为登录接口 // expires: new Date(Date.now() + 25892000000), // httpOnly: true, // }); res.cookie("signinToken", token, { expires: new Date(Date.now() + 25892000000), httpOnly: true, }); if (isMatch) { return res.status(200).json({ message: "登录成功" }); } else { return res.status(400).json({ error: "登录凭证无效" }); } } else { return res.status(400).json({ error: "登录凭证无效" }); } } catch (error) { console.log(error); } }); // 收藏列表模块(需JWT验证用户身份) router.get("/watchlist", Auth, (req, res) => { res.send(req.rootuser); }); // 退出登录模块 router.get("/signout", (req, res) => { res.clearCookie("signinToken", { path: "/" }); res.status(200).send("退出登录成功"); }); module.exports = router;
Auth.js(JWT验证中间件)
const jwt = require("jsonwebtoken"); const User = require("../model/newUserSchema"); const SECRETKEY = "myScretKeyyyyyyyyyyyyeeee"; const Auth = async (req, res, next) => { try { const token = req.cookies.signinToken; if (!token) { console.log("未找到Token"); return res.sendStatus(403); } const verifytoken = jwt.verify(token, SECRETKEY); const rootuser = await User.findOne({ _id: verifytoken._id, "tokens.token": token }); if (!rootuser) { throw new Error("用户不存在"); } req.token = token; req.rootuser = rootuser; req.UserID = rootuser._id; next(); } catch (error) { res.status(401).send("未授权访问:未找到有效Token"); console.log(error); } }; module.exports = Auth;
内容的提问来源于stack exchange,提问作者Tapesh Patel
相关产品推荐
相关产品推荐

