Node.js、Angular、express-session:由于 cookie 策略(sameSite cookie),Chrome 80 不保存会话

Posted

技术标签:

【中文标题】Node.js、Angular、express-session:由于 cookie 策略(sameSite cookie),Chrome 80 不保存会话【英文标题】:Node.js, Angular, express-session: Chrome 80 does not save session because of cookie policy (sameSite cookies) 【发布时间】:2020-07-16 12:56:29 【问题描述】:

我有一个 Node.js,Angular 应用程序。 (用 TypeScript 编写的 Node.js 服务器)。 Node.js 服务器在 Amazon EC-2 实例上运行,Angular 客户端在另一台服务器上。

对于登录会话,我使用 express-session。我没有在应用程序中使用 cookie,所以我认为问题出在 express-session cookie 上。 在 Firefox 上它可以正常工作,但在 Google Chrome (80.0.3987.149) 上它不能工作:Chrome 不保存会话(所以我不能离开登录页面)并警告:

在没有SameSite 属性的情况下设置了与http://addressof.myserverapp.com/ 的跨站点资源关联的cookie。它已被阻止,因为 Chrome 现在仅在使用 SameSite=NoneSecure 设置时才提供带有跨站点请求的 cookie。您可以在 Application>Storage>Cookies 下的开发者工具中查看 cookie,并在 https://www.chromestatus.com/feature/5088147346030592 和 https://www.chromestatus.com/feature/5633521622188032 查看更多详细信息。

在 Node.js 服务器中,我以这种方式设置快速会话:

import cookieParser from 'cookie-parser';
app.use(cookieParser(secret));

app.use(session(
    secret: secret,
    resave: false,
    saveUninitialized: false,
    cookie: 
        httpOnly: false,
        maxAge: null,
        secure: true,
        sameSite: 'none'
    ,
    store: sessionStore // mysqlStore - express-mysql-session
));

我也试过用这个代码sn-p解决问题(来自https://github.com/expressjs/session/issues/725#issuecomment-605922223)

Object.defineProperty(session.Cookie.prototype, 'sameSite', 
    // sameSite cannot be set to `None` if cookie is not marked secure
    get() 
        return this._sameSite === 'none' && !this.secure ? 'lax' : this._sameSite;
    ,
    set(value) 
        this._sameSite = value;
    
);

服务器 npm 包:

"cors": "^2.8.5",
"cookie-parser": "^1.4.5",
"express": "^4.17.1",
"express-mysql-session": "^2.1.3",
"express-session": "^1.17.0",
Npm version: 6.13.4
Node version: 12.16.1

我花了几天的时间来解决这个问题来弄清楚我做错了什么......

【问题讨论】:

您能否提供一个正在发送的Set-Cookie 标头的示例?正如您所指出的,express-session 看起来确实应该支持SameSite=None; Secure 属性,因此我们需要查看发送和接收的内容。我们在这里有更完整的调试指南:chromium.org/updates/same-site/test-debug 【参考方案1】:

这里的问题是您通过 HTTP 访问网站,但 cookie secure 设置为 true,这意味着它只会通过 HTTPS 发送。

如果您在express-session cookie 选项中设置secure: false,它将起作用:

import cookieParser from 'cookie-parser';
app.use(cookieParser(secret));

app.use(session(
    secret: secret,
    resave: false,
    saveUninitialized: false,
    cookie: 
        httpOnly: false,
        maxAge: null,
        // allow the cookie to be sent via HTTP ("true" means "HTTPS only)
        secure: false, 
        sameSite: 'none'
    ,
    store: sessionStore
));

【讨论】:

secure: false 在 Chrome 80+ 中无法与 sameSite: 'none' 一起使用

以上是关于Node.js、Angular、express-session:由于 cookie 策略(sameSite cookie),Chrome 80 不保存会话的主要内容,如果未能解决你的问题,请参考以下文章

node.js 安装express 提示 command is not found

Angular JS 和 node.js

将 JSON 从 angular.js 发送到 node.js

每次刷新或访问页面时,Node js express-session都会创建新的会话ID

Angular.js 的 Node.js CORS 会话 cookie

Angular、Node.js、MySQL 图片上传