java 有效 Cookie 值的明确指南

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6108207/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 14:21:31  来源:igfitidea点击:

Definite guide to valid Cookie values

javahttp

提问by mP.

I know there are other questions but they seem to have answers which are assumptions rather than being definitive.

我知道还有其他问题,但他们的答案似乎是假设而不是确定的。

My limited understanding is that cookie values are:

我有限的理解是 cookie 值是:

  • semi-colons are already used to separate cookies attributes within a single cookie.
  • equals signs are used to separate cookie names and values
  • colons are used to separate multiple cookies within a header.
  • 分号已用于分隔单个 cookie 中的 cookie 属性。
  • 等号用于分隔 cookie 名称和值
  • 冒号用于分隔标题中的多个 cookie。

Are there any other "special" characters ?

还有其他“特殊”字符吗?

Some other q/a suggest that one base64 encodes the value but this does of course may include equals signs which of course are not valid.

其他一些 q/a 建议使用 base64 对值进行编码,但这当然可能包括等号,这当然是无效的。

i have also seen some suggestions that values may be quoted this however leads to other questions.

我还看到一些建议,可能会引用值,但这会导致其他问题。

  • do the special characters need to be quoted ?
  • do quoted values support the usual backslash escaping mechanisms.
  • 特殊字符需要加引号吗?
  • 引用的值是否支持通常的反斜杠转义机制。

RFC I read a few RFCs including some of the many cookie RFCS but i am still unsure as there is cross reference to another RFC etc with no definitive simple explaination or sample that "answers" my query.

RFC 我阅读了一些 RFC,包括许多 cookie RFCS 中的一些,但我仍然不确定,因为有对另一个 RFC 等的交叉引用,没有明确的简单解释或“回答”我的查询的样本。

Hopefully no one will say read the RFC because the question becomes which RFC...?

希望没有人会说阅读 RFC,因为问题变成了哪个 RFC...?

I think i have also read that different browsers have slightly different rules so hopefully please note this in your answers if this matters.

我想我也读过不同的浏览器的规则略有不同,所以如果这很重要,希望请在你的答案中注明。

回答by Stephen C

The latest RFC is 6265, and it states that previous Cookie RFCs are obsoleted.

最新的 RFC 是6265,它指出以前的 Cookie RFC 已过时。

Here's what the syntax rules in the RFC say:

这是 RFC 中的语法规则所说的:

 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

Thus:

因此:

  • The special characters are white-space characters, double quote, comma, semicolon and backslash. Equals is not a special character.

  • The special characters cannot be used at all, with the exception that double quotes may surround the value.

  • Special characters cannot be quoted.

  • Backslash does not act as an escape.

  • 特殊字符是空格字符、双引号、逗号、分号和反斜杠。等于不是特殊字符。

  • 根本不能使用特殊字符,但值周围可能有双引号。

  • 不能引用特殊字符。

  • 反斜杠不能用作转义符。

It follows that base-64 encoding can be used, because equals is not special.

因此可以使用 base-64 编码,因为 equals 并不特殊。

Finally, from what I can tell, the RFC 6265 cookie values are defined so that they will work with any browser that implements any of the Cookie RFCs. However, if you tried to use cookie values that don't conform to RFC 6265 (but do arguably do conform to earlier RFCs), you may find that cookie behavior varies with different browsers.

最后,据我所知,定义了 RFC 6265 cookie 值,以便它们可以与实现任何 Cookie RFC 的任何浏览器一起使用。但是,如果您尝试使用不符合 RFC 6265 的 cookie 值(但可以说确实符合早期 RFC),您可能会发现 cookie 行为因浏览器而异。

In short, conform to the letter of RFC 6265 and you should be fine.

总之,符合RFC 6265的信,你应该没问题。

If you need pass cookie values that include any of the forbidden characters, your application needs to do its own encoding and decoding of the values; e.g. using base64.

如果您需要传递包含任何禁止字符的 cookie 值,您的应用程序需要对这些值进行自己的编码和解码;例如使用base64。

回答by Johan

There was the mention of base64, so here is a cooked cookie solution using that in cookies. The functions are about a modified version of base64, they only use [0-9a-zA-Z_-]

提到了 base64,所以这里有一个在 cookie 中使用它的熟 cookie 解决方案。这些函数是关于 base64 的修改版本,它们只使用 [0-9a-zA-Z_-]

You can use it for both the name and value part of cookies, is binary safe, as they say.

您可以将它用于 cookie 的名称和值部分,正如他们所说,它是二进制安全的。

The gzdeflate/gzinflate takes back 30% or so space created by base64, could not resist using it. Note that php gzdeflate/gzinflate is only available in most hosting companies, not all.

gzdeflate/gzinflate 收回了由 base64 创建的 30% 左右的空间,无法抗拒使用它。请注意,php gzdeflate/gzinflate 仅适用于大多数托管公司,而不是所有托管公司。

//write
setcookie
         (
         'mycookie'
         ,code_base64_FROM_bytes_cookiesafe(gzdeflate($mystring))
         ,time()+365*24*3600
         );
//read
$mystring=gzinflate(code_bytes_FROM_base64_cookiesafe($_COOKIE['mycookie']));


function code_base64_FROM_bytes_cookiesafe($bytes)
    {
    //safe for name and value part [0-9a-zA-Z_-]
    return strtr(base64_encode($bytes),Array
            (
            '/'=>'_',
            '+'=>'-',
            '='=>'',
            ' '=>'',
            "\n"=>'',
            "\r"=>'',
            ));
    }


function code_bytes_FROM_base64_cookiesafe($enc)
    {
    $enc=str_pad($enc,strlen($enc)%4,'=',STR_PAD_RIGHT);//add back =
    $enc=chunk_split($enc);//inserts \r\n every 76 chars
    return base64_decode(strtr($enc,Array
            (
            '_'=>'/',
            '-'=>'+',
            )));
    }