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

huangapple go评论102阅读模式
英文:

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以获取标题值的带引号字符串语义:

HTTP RFC 7230 3.2.6.

以下字符包括在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(&quot;Set-Cookie&quot;, &quot;your_cookie_name=&quot;+string(b)+&quot;; Path=/; Domain=localhost; Secure; Max-Age=999999999; SameSite=Strict&quot;)

Since you'll probably use cURL to test sending cookies to the server, here's a useful test:

curl --insecure --cookie &#39;test1={&quot;test1&quot;:&quot;v1&quot;}; test2={&quot;test2&quot;:&quot;v2&quot;}&#39;  https://localhost:8081/

Which results in a HTTP header like the following:

GET / HTTP/2.0
Host: localhost:8081
Accept: */*
Cookie: test1={&quot;test1&quot;:&quot;v1&quot;}; test2={&quot;test2&quot;:&quot;v2&quot;}
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: &quot;Google Chrome&quot;;v=&quot;107&quot;, &quot;Chromium&quot;;v=&quot;107&quot;, &quot;Not=A?Brand&quot;;v=&quot;24&quot;

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:

HTTP RFC 7230 3.2.6.

These characters are included for quoted-string:

HTAB, SP
!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~
%x80-FF

The characters " and / may be included if escaped.

huangapple
  • 本文由 发表于 2021年7月30日 05:16:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/68582862.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定