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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 03:45:34