Go:如何不删除 cookie 上的双引号

Go: how to not remove double quotes on cookies

Go 删除​​了 cookie 中的双引号。有没有办法在 Go 中的 cookie 中保留双引号?

例如,我要发送一条小 JSON 消息,并且“SetCookie”会去掉双引号。

w.SetCookie("my_cookie_name", small_json_message)

关于 Cookie 的更多信息:

  1. ; 是规定的 cookie 分隔符。

  2. RFC 明确表示 cookie 值中允许使用双引号:cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )

  3. 如果 JSON 字符串不包含字符 ; 并且被压缩,则不会有问题。没有分号的附加约束不是什么大问题,可以轻松转义或删除。

  4. 我已经确认使用简单的 k:v JSON 有效载荷进行测试,它在所有主流浏览器上都运行良好,没有任何问题。

  5. RFC 并没有说 DQUOTE 在 cookie 的其他地方无效(第 1 点),它说 whitespace DQUOTE 不是 只是DQUOTE,是无效的。 压缩的 JSON 字符串没有这个问题

  6. Cookie 通常由服务器数据而非用户数据生成。我建议不要使用任意 JSON,比如用户生成的 JSON,作为 cookie。

JSON 轻松符合cookie RFC。此外,尽管 JSON 这个例子不是问题,但关于不符合 RFC 的假设问题:

  1. Cookie 作为 HTTP headers 传输。许多 HTTP headers 通常无视 RFC。例如,由 Chrome 创建的 Sec-Ch-Ua header 包含几个“坏”字符。

Sec-Ch-Ua: "Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"

  1. “逗号”是“不允许的”,并且一直在使用。
  2. 即使双引号是“错误的”,但事实并非如此,但如果是的话,有很多 in-the-wild 个包含引号的 cookie 示例。

供参考,这里是 relevant section of RFC 6265

set-cookie-header = "Set-Cookie:" SP set-cookie-string
 set-cookie-string = cookie-pair *( ";" SP cookie-av )
 cookie-pair       = cookie-name "=" cookie-value
 cookie-name       = token
 cookie-value      = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
 cookie-octet      = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
                       ; US-ASCII characters excluding CTLs,
                       ; whitespace DQUOTE, comma, semicolon,
                       ; and backslash

可以看到 whitespace DQUOTE 是不允许的,DQUOTE 是允许的。

这是一种手动设置 cookie 的方法,其中 w 是 http.responseWriter,b 是 cookie 的字节数。

w.Header().Set("Set-Cookie", "your_cookie_name="+string(b)+"; Path=/; Domain=localhost; Secure; Max-Age=999999999; SameSite=Strict")

Max-Age 以秒为单位,999999999 为 ~31.69 年。

由于您可能会使用 cURL 来测试向服务器发送 cookie,这里有一个有用的测试:

curl --insecure --cookie 'test1={"test1":"v1"}; test2={"test2":"v2"}'  https://localhost:8081/

这导致 HTTP header 如下所示:

GET / HTTP/2.0
Host: localhost:8081
Accept: */*
Cookie: test1={"test1":"v1"}; test2={"test2":"v2"}
User-Agent: curl/7.0.0

HTTP cookies are allowed to have double quotes.

你确定吗? rfc6265 状态:

set-cookie-header = "Set-Cookie:" SP set-cookie-string
set-cookie-string = cookie-pair *( ";" SP cookie-av )
cookie-pair       = cookie-name "=" cookie-value
cookie-name       = token
cookie-value      = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
cookie-octet      = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
                       ; US-ASCII characters excluding CTLs,
                       ; whitespace DQUOTE, comma, semicolon,
                       ; and backslash

因此 Go 似乎遵循了规范(规范之前将DQUOTE 定义为 double quote)。

有关详细信息,请参阅 this issue