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 的更多信息:
;
是规定的 cookie 分隔符。
RFC 明确表示 cookie 值中允许使用双引号:cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
如果 JSON 字符串不包含字符 ;
并且被压缩,则不会有问题。没有分号的附加约束不是什么大问题,可以轻松转义或删除。
我已经确认使用简单的 k:v JSON 有效载荷进行测试,它在所有主流浏览器上都运行良好,没有任何问题。
RFC 并没有说 DQUOTE
在 cookie 的其他地方无效(第 1 点),它说 whitespace DQUOTE
, 不是 只是DQUOTE
,是无效的。 压缩的 JSON 字符串没有这个问题。
Cookie 通常由服务器数据而非用户数据生成。我建议不要使用任意 JSON,比如用户生成的 JSON,作为 cookie。
JSON 轻松符合cookie RFC。此外,尽管 JSON 这个例子不是问题,但关于不符合 RFC 的假设问题:
- 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"
- “逗号”是“不允许的”,并且一直在使用。
- 即使双引号是“错误的”,但事实并非如此,但如果是的话,有很多 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。
Go 删除了 cookie 中的双引号。有没有办法在 Go 中的 cookie 中保留双引号?
例如,我要发送一条小 JSON 消息,并且“SetCookie”会去掉双引号。
w.SetCookie("my_cookie_name", small_json_message)
关于 Cookie 的更多信息:
;
是规定的 cookie 分隔符。RFC 明确表示 cookie 值中允许使用双引号:
cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
如果 JSON 字符串不包含字符
;
并且被压缩,则不会有问题。没有分号的附加约束不是什么大问题,可以轻松转义或删除。我已经确认使用简单的 k:v JSON 有效载荷进行测试,它在所有主流浏览器上都运行良好,没有任何问题。
RFC 并没有说
DQUOTE
在 cookie 的其他地方无效(第 1 点),它说whitespace DQUOTE
, 不是 只是DQUOTE
,是无效的。 压缩的 JSON 字符串没有这个问题。Cookie 通常由服务器数据而非用户数据生成。我建议不要使用任意 JSON,比如用户生成的 JSON,作为 cookie。
JSON 轻松符合cookie RFC。此外,尽管 JSON 这个例子不是问题,但关于不符合 RFC 的假设问题:
- 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"
- “逗号”是“不允许的”,并且一直在使用。
- 即使双引号是“错误的”,但事实并非如此,但如果是的话,有很多 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。