Express 会话未将安全 cookie 发送到本地主机

问题描述 投票:0回答:3

通过

res.cookie(..., {secure: true})
的常规 cookie 可以工作,但快速会话则不行。我做了以下演示:

const express = require('express');
const session = require('express-session');
const app = express();
app.use(session({
    secret: 'qwerqwerqwer',
    resave: true,
    saveUninitialized: true,
    cookie: {
        secure: true,
    },
}));
app.get('/hello', (req, res) => {
    res.cookie('test', 'asdf', {secure: true});
    res.send('');
});
const PORT = 7000;
app.listen(PORT, () => {
    console.log(`backend listening on port ${PORT}`);
});

当我去

/hello
时,
Set-Cookie
有一个
test: asdf
,但没有
Set-Cookie
connect.sid
。换句话说,express-session 根本不发送 cookie;这不是浏览器端的问题。我还记录了响应标头,它确实不包含
Set-Cookie
代表
connect.sid

MDN 表示安全 cookie 适用于本地主机。对于 chrome 来说可能不是这样,但他们说对于 Firefox 来说是这样,所以我下载了 Firefox 并在其上进行了测试,但我没有收到

connect.sid
cookie,这也证实了这是
express-session
的问题。

我认为express-session越权了,出于某种原因扣留了cookie(无论如何,安全属性应该由浏览器解释)。我该如何解决这个问题?

node.js express cookies localhost express-session
3个回答
2
投票

我做了一些更多的挖掘,结果发现这是express-session的一个已知问题:https://github.com/expressjs/session/issues/837

基本上,有关安全 cookie 的文档已经发生了变化。过去,服务器应该通过 HTTP 保留安全 cookie,这就是 express-session 所实现的。现在,它已经变成了客户的责任。


1
投票

安全 cookie 仅通过 HTTPS 发送,因此在开发中,您应该添加检查以查看您是在生产环境中运行还是在本地运行,如下所示:

app.use(session({
    secret: 'qwerqwerqwer',
    resave: true,
    saveUninitialized: true,
    cookie: {
        secure: process.env.NODE_ENV === "production",
    },
}));

0
投票

我也有类似的问题。我的本地主机上没有 HTTPS,因此无法使用

sameSite: 'none'
(需要 HTTPS)。所以我选择了
sameSite: 'strict'

但是,我在 localhost

127.0.0.1:3000
上的客户端不断被 Chrome 中我的服务器 (
127.0.0.1
) cookie 控件拒绝,尽管它在 Insomnia/Postman 和 Firefox 中运行良好。

问题是——也许很明显——服务器在

http://127.0.0.1:xxxx
上运行,而我来自客户端的请求(GET POST PUT 等)是在
http://localhost:xxxx
上运行。它在 Firefox(和 Insomnia/Postman)中运行良好,但如前所述,在 Chrome 中不行。

当我将客户端应用程序请求从

localhost
更改为
127.0.0.1
时,它也可以在 Chrome 中运行。与 Firefox 不同,Chrome 似乎并不将
localhost
127.0.0.1
视为“sameSite”。

我的会话/cookie 设置:

const expire = 1000 * 60 * 60 * 24 * 5 // 5 days
app.use( session( {
    name: process.env.SESSION_NAME, // sessionname in .env
    resave: true,
    rolling: false,
    saveUninitialized: false,
    store: MongoStore.create( { mongoUrl: process.env.DB_URL } ), // connectionstring in .env
    secret: 'process.env.SESSION_SECRET', // secret in .env
    cookie: {
        maxAge: expire,
        sameSite: "strict", //"none" requires https ... "lax" only works with GET
        secure: process.env.NODE_ENV === "production", // true when production/https otherwise false
        httpOnly: false
    }
} ) )
© www.soinside.com 2019 - 2024. All rights reserved.