【问题标题】:Only first cookie in set-cookie header is set (after Firebase hosting rewrites to function)仅设置了 set-cookie 标头中的第一个 cookie(在 Firebase 托管重写为功能之后)
【发布时间】:2020-02-03 15:06:01
【问题描述】:

我正在尝试从 express 节点后端以单一响应的形式发送多个 cookie。 Set-cookie 标头设置了看似有效的值,但除了第一个之外,没有任何 cookie 被存储。这可能是什么原因造成的?是否有可能其他一些标头以某种方式干扰?

app.post("/api/test", function(req, res) {
    res.cookie("age", "44");
    res.cookie("name", "ok");
    res.cookie("something", "else");
    res.send("cookies set");
});

标题中的结果

Access-Control-Allow-Credentials: true
Cache-Control: private
Content-Type: text/html; charset=utf-8
Etag: W/"b-AindM8n+eJQTR6jb7Hg8S4fG8qI"
Expires: Sat, 05 Oct 2019 16:18:12 GMT
Function-Execution-Id: r7d6qjgl5noi
Server: Google Frontend
X-Cloud-Trace-Context: 051139bdc4cc753cad51c0dd3e89e0b8;o=1
X-Powered-By: Express
Content-Length: 11
Accept-Ranges: bytes
Date: Sat, 05 Oct 2019 16:18:12 GMT
Connection: keep-alive
Set-Cookie: age=44; path=/,name=ok; path=/,something=else; path=/
X-Served-By: cache-ams21036-AMS
X-Cache: MISS
X-Cache-Hits: 0
X-Timer: S1570292292.302186,VS0,VE410
Vary: Origin,cookie,need-authorization, x-fh-requested-host, accept-encoding

我希望这会在浏览器中存储 3 个 cookie,但始终只保存第一个。

编辑:

经过进一步调查,set-cookie 标头被写为逗号分隔的单行代码的原因最终被 Firebase 托管以重写功能。

{
   "source": "/{,/**}",
   "function": "testingexpress"
}

【问题讨论】:

    标签: express cookies http-headers google-cloud-functions firebase-hosting


    【解决方案1】:

    经过进一步调查,set-cookie 标头被写为逗号分隔的单行代码的原因最终被 Firebase 托管以重写功能。报告为错误。

    【讨论】:

    • 这方面有什么进一步的细节吗?有什么办法可以解决这个问题?非常感谢
    • 仅供参考,此错误现已修复。您应该能够按预期发送多个 Set-Cookie 标头。您介意更新答案以反映这一点吗?
    • @MichaelBleigh 肯定发生了一些变化,我不能再在 Cloudflare 后面的 Firebase 托管后面的 CloudRun 上使用 __session cookie。不确定到底是怎么回事,但看起来我的 __session cookie 现在已删除,无法再登录我的 CMS
    • 我想我找到了原因,在您说您现在在一行中支持多个 cookie 的消息中,但 Expires 的日期格式包含一个逗号,如 tools.ietf.org/html/rfc2616#section-3.3.1 因此看起来您是在日期中间用这个逗号分割 cookie
    • 是的,我们今天刚刚遇到了这个错误。我们正在研究它,但与此同时,我建议在 Set-Cookie 标头中使用 max-age 而不是 expires。
    【解决方案2】:

    似乎某些版本的 express 可能会生成无效的或至少经常不兼容的 cookie 标头 (syntax of a cookie header, RFC 6265),其中多个 cookie 出现一个 Set-Cookie 标头。更标准的方法是在响应中提供多个 Set-Cookie 标头。

    值得注意的是,从上面的 RFC 中,这也是 excerpt:

    源服务器不应将多个 Set-Cookie 标头字段折叠到 单个标题字段。折叠 HTTP 标头的常用机制 字段(即,如 [RFC2616] 中定义的)可能会改变 Set-Cookie 标头字段,因为使用了 %x2C (",") 字符 通过 Set-Cookie 以与此类折叠冲突的方式。

    本文档记录了一种可能的解决方法,并且是从 2014 年左右开始的:http://www.connecto.io/blog/nodejs-express-how-to-set-multiple-cookies-in-the-same-response-object/

    我无法使用 express 4.17.1 复制此内容(类似代码生成多个 Set-Cookie 标头)。看起来行为可能在 4.13.0 左右发生了变化:https://github.com/expressjs/express/commit/5915894af3f14e75dd3121fdc2d92ae55206e398

    我会考虑更新您的 Express 版本,或使用上述链接文章中的解决方法。

    【讨论】:

    • 我正在运行相同的节点版本并尝试了解决方法仍然没有运气。所以我认为原因一定是在其他地方,并意识到我一直在 Firebase 函数上运行 express。我在本地对其进行了测试,它完美地工作。我猜测的是,已部署的 Firebase 版本将标头和格式 set-cookie 重写为过时的逗号分隔格式。
    • @llusi 有趣。使用已部署或本地提供的 firebase 功能来测试这一点,我看不到重写。如果您确实看到了差异,那可能值得联系支持人员。但是,您提供的代码似乎不是 firebase 函数。 (它使用“app.post”,通常不会出现在 firebase 函数中)。
    • 在进一步测试后,最终的原因是 firebase 函数被从主机重写重定向,例如 { "source": "/app/**", "function": "testingexpress" } 函数没有托管重写结果工作正常
    • 看起来可能值得reporting
    • @llusi 既然是你自己找到的答案,最好把答案贴出来并接受,以便关闭这个帖子。
    猜你喜欢
    • 1970-01-01
    • 2018-08-29
    • 1970-01-01
    • 2020-08-16
    • 2015-09-12
    • 1970-01-01
    • 2019-11-12
    • 2017-07-01
    • 1970-01-01
    相关资源
    最近更新 更多