英文:
Go: how to not remove double quotes on cookies
问题
Go在cookie中删除了双引号。有没有办法在Go中保留cookie中的双引号?
例如,我发送了一条小的JSON消息,但"SetCookie"会删除双引号。
w.SetCookie("my_cookie_name", small_json_message)
关于Cookie的更多信息:
-
HTTP RFC定义了带引号的字符串值。请参阅https://www.rfc-editor.org/rfc/rfc7230#section-3.2.6
-
提议的cookie RFC明确表示允许在cookie值中使用双引号:
cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
-
Go目前有一个条件在cookie中插入双引号,所以显然允许使用双引号。
-
;
是cookie的分隔符。 -
值中包含ASCII字符范围之外的ASCII字符可能会被引用(RFC将其称为
quoted_string
),这扩展了允许的字符集。 -
JSON不包含
;
字符,因此要在JSON中出现;
,它只能出现在字符串值中。在JSON中,字符串值已经被引用。 -
我已经确认使用简单的k:v JSON有效载荷进行了测试,在所有主要浏览器上都没有问题。
-
Cookie通常由服务器数据生成,而不是用户数据。这意味着可以使用良好结构化的、而不是任意的JSON。
JSON很容易符合cookie RFC。此外,即使在这个JSON示例中没有问题,关于不符合RFC的假设性关注:
- Cookie作为HTTP头传输。许多常见的HTTP头通常不遵循RFC。例如,由Chrome创建的
Sec-Ch-Ua
头包含几个“不良”字符。
Sec-Ch-Ua: "Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"
- “逗号”是“不允许的”,但它经常被使用。
- 即使双引号是“错误的”,实际上它们并不是,但即使是这样,也有很多包含引号的cookie的实际例子。
供参考,这是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
是允许的。
英文:
Go removes double quotes in cookies. Is there a way to keep double quotes in cookies in Go?
For example, I'm sending a small JSON message and "SetCookie" strips double quote.
w.SetCookie("my_cookie_name", small_json_message)
More about Cookies:
-
The HTTP RFC defines quoted string values. See https://www.rfc-editor.org/rfc/rfc7230#section-3.2.6
-
The proposed cookie RFC explicitly says double quotes are allowed in cookie values:
cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
-
Go currently has a condition to insert double quote into cookies, so obviously double quotes are allowed.
-
;
is the cookie delimiter. -
Values with ASCII characters outside the limited ASCII range may be quoted (The RFC calls this the
quoted_string
) which expands the allowed character set. -
JSON does not contain the
;
character, so for;
to appear in JSON it can only appear in string values. In JSON, string values are already quoted. -
I've confirmed testing using a simple k:v JSON payload and it works fine on all major browsers with no issues.
-
Cookies are typically generated by server data, not user data. This means well structured, not arbitrary, JSON may be used
JSON easily can conform to the cookie RFC. Additionally, even though it's not an issue with this example of JSON, regarding the hypothetical concern of not conforming to the RFC:
- A cookie is transmitted as a HTTP headers. Many HTTP headers commonly disregard the RFC. For example, the
Sec-Ch-Ua
header created by Chrome, includes several "bad" characters.
Sec-Ch-Ua: "Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"
- "comma" is "disallowed" and it's used all the time.
- Even if double quotes were "wrong", which they are not, but if they were, there are lots of in-the-wild examples of cookies containing quotes.
For reference, here's the 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
Where one can see whitespace DQUOTE
is disallowed and DQUOTE
is allowed.
答案1
得分: 2
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
定义为双引号
)。
有关更多信息,请参见此问题。
英文:
> HTTP cookies are allowed to have double quotes.
Are you sure? rfc6265 states:
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
So it appears that Go is following the specification (the spec previously definesDQUOTE
to mean double quote
).
See this issue for further information.
答案2
得分: -1
是的。双引号在cookie和其他HTTP头部中是允许的。双引号也用于转义否则无效的字符。
以下是手动设置cookie的方法,其中w
是http.responseWriter,b
是cookie的字节。Max-Age以秒为单位,999999999大约等于31.69年。
w.Header().Set("Set-Cookie", "your_cookie_name="+string(b)+"; Path=/; Domain=localhost; Secure; Max-Age=999999999; SameSite=Strict")
由于您可能会使用cURL测试向服务器发送cookie,这里有一个有用的测试示例:
curl --insecure --cookie 'test1={"test1":"v1"}; test2={"test2":"v2"}' https://localhost:8081/
这将生成以下类似的HTTP头部:
GET / HTTP/2.0
Host: localhost:8081
Accept: */*
Cookie: test1={"test1":"v1"}; test2={"test2":"v2"}
User-Agent: curl/7.0.0
还要注意,许多RFC规则经常被忽略,尤其是逗号。例如,Chrome设置了以下头部:
Sec-Ch-Ua: "Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24"
哇!它使用了逗号和其他字符!尽管RFC似乎表示不允许,但已经确立了HTTP头部中的逗号是可以的。
请注意,Chrome头部使用了空格、许多双引号、逗号、特殊字符和分号。Chrome在需要转义的许多值周围使用双引号,这是符合RFC的正确方式。
请注意,cookie RFC 6265是一个“提案”,已经存在了11年。有其原因。知道cookie只是一个HTTP头部,查看接受的HTTP RFC以获取标题值的带引号字符串语义:
以下字符包括在quoted-string
中:
HTAB、SP
!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~
%x80-FF
如果需要,可以包括字符"和/进行转义。
英文:
Yes. Double quotes are allowed in cookies and other HTTP headers. Double quotes are also used to escape characters that would be otherwise invalid.
Here's a way to manually set a cookie, where w
is the http.responseWriter and b
is the bytes of the cookie. Max-Age is in seconds and 999999999 is ~31.69 years.
w.Header().Set("Set-Cookie", "your_cookie_name="+string(b)+"; Path=/; Domain=localhost; Secure; Max-Age=999999999; SameSite=Strict")
Since you'll probably use cURL to test sending cookies to the server, here's a useful test:
curl --insecure --cookie 'test1={"test1":"v1"}; test2={"test2":"v2"}' https://localhost:8081/
Which results in a HTTP header like the following:
GET / HTTP/2.0
Host: localhost:8081
Accept: */*
Cookie: test1={"test1":"v1"}; test2={"test2":"v2"}
User-Agent: curl/7.0.0
Also note, many of the RFC rules are ignored all the time, especially commas. For example, Chrome sets this header:
Sec-Ch-Ua: "Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24"
Gasp! Is uses commas and other things! It is well established that commas in HTTP headers are okay, even though the RFC appears to say otherwise.
Note that the Chrome header uses spaces, many double quotes, commas, special characters, and semi colon. Chrome here uses double quotes around many values needing escaping, and that's the right way to be compliant with the RFC.
Note that the cookie RFC 6265 is a proposal and has been for 11 years. There are reasons for that. Knowing that cookies are just a HTTP header, look at the accepted HTTP RFC for quoted string semantic for header values:
These characters are included for quoted-string
:
HTAB, SP
!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~
%x80-FF
The characters " and / may be included if escaped.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论