NodeJS express-session:Postman会话正常但浏览器无法获取问题求助
问题:express-session在浏览器中无法获取会话userid属性,Postman正常
我正在开发一个使用express-session管理会话的NodeJS项目,遇到以下问题:
- 向
http://localhost:5500/api/login发送POST请求后,服务端会创建带有自定义userid属性的会话 - 使用Postman向
http://localhost:5500/发送GET请求时,服务端能正常获取到带userid的会话并返回正确响应 - 但使用Chrome等浏览器发送该GET请求时,服务端无法获取到登录时添加的
userid属性,无法正确响应
项目代码
index.js
const express = require("express") const app = express() const PORT = process.env.PORT || 5500 const session = require("express-session") const { routers } = require("./routes/routes") const mongoose = require("mongoose") const cookieParser = require("cookie-parser") const TIME = 1000 * 60 * 5 app.use(cookieParser()) app.use( session({ secret: "iamnamdo1234567", saveUninitialized: true, cookie: { maxAge: TIME, sameSite: "strict" }, resave: false }) ) const URI = process.env.DB_CONNECTION app.use(express.urlencoded({ extended: true })) app.use(express.json()) app.use("/api", routers) app.get("/", (req, res) => { let session = req.session.userid session ? res.status(200).send("Hello my friend, you are logged in") : res.status(400).send("You need to log in") }) mongoose.connect(URI, { useNewUrlParser: true.valueOf(), useUnifiedTopology: true }, err => { if (err) { console.log(err) } else { console.log("database connected") } }) app.listen(PORT, () => { console.log(`Go to http://localhost:${PORT}`) })
routes.js
const express = require("express") const route = express.Router() const { User } = require("../models/User") const bcrypt = require("bcrypt") const errorHandler = (type, error) => { if (type === "register") { if (error.code === 11000) { return { message: "Username has been taken" } } else if (error._message === "User validation failed") { return { message: error.errors.username?.properties.message || error.errors.password?.properties.message } } } else if (type === "login") { return { message: `${error}` } } } route.post("/register", async (req, res) => { try { const { username, password } = req.body const user = await User.create({ username, password }) res.status(200).send("User has been created successfully") } catch (error) { // console.log(error) let message = errorHandler("register", error) res.status(400).send(message) } }) route.post("/login", async (req, res) => { const { username, password } = req.body try { const user = await User.findOne({ username }) if (!user) { throw (new Error().message = "Username not found") } const checkPassword = await bcrypt.compare(password, user.password) if (checkPassword === false) { throw (new Error().message = "Password is incorrect") } else { req.session.userid = user.username console.log(req.session.userid) res.status(200).send("Logged in") } } catch (error) { let message = errorHandler("login", error) res.status(400).send(message) } }) route.post("/logout", (req, res) => { req.session.destroy() res.redirect("/") }) module.exports.routers = route
原因分析及解决方法
1. 前端请求未携带凭证
如果是通过前端JS(如fetch、axios)发起GET请求,需要显式配置携带会话凭证:
- fetch示例:
fetch('/', { credentials: 'include' }) - axios示例:
axios.get('/', { withCredentials: true })
浏览器默认在跨域请求时不会自动携带Cookie,同域请求虽默认携带,但JS发起的请求可能需要显式声明。
2. SameSite Cookie配置问题
当前设置sameSite: "strict",会严格限制Cookie在跨站场景下的携带。如果你的登录请求和GET请求是同域的,这个设置没问题;但如果是前端页面在其他端口/域名发起请求,需调整为:
session({ secret: "iamnamdo1234567", saveUninitialized: false, cookie: { maxAge: TIME, sameSite: "lax", // 宽松模式允许同站及部分跨站请求携带Cookie // 若使用HTTPS,可添加secure: true(配合sameSite: "none"时必须设置) }, resave: false })
3. saveUninitialized设置不当
saveUninitialized: true会保存未修改的空会话,可能导致Cookie被提前创建,覆盖登录后的会话数据。建议改为saveUninitialized: false,仅保存已修改的会话。
4. 检查浏览器Cookie状态
打开浏览器开发者工具(F12),进入Application > Cookies > http://localhost:5500,确认connect.sid Cookie存在,且路径为/、过期时间正常。如果Cookie不存在,说明登录请求没有正确设置Cookie;如果存在但请求未携带,需检查SameSite和凭证配置。
5. 确认请求域名/端口一致
确保浏览器请求的域名和端口与登录请求完全一致(均为localhost:5500),不同端口/域名会被视为不同站点,浏览器不会跨域携带Cookie。
内容的提问来源于stack exchange,提问作者do huynhnam
相关产品推荐
相关产品推荐

