【问题标题】:Definite guide to valid Cookie values有效 Cookie 值的明确指南
【发布时间】:2011-05-24 09:13:11
【问题描述】:

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

我的有限理解是 cookie 值是:

  • 分号已用于分隔单个 cookie 中的 cookie 属性。
  • 等号用于分隔 cookie 名称和值
  • 冒号用于分隔标头中的多个 cookie。

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

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

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

  • 特殊字符需要加引号吗?
  • 引用的值是否支持常用的反斜杠转义机制。

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

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

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

【问题讨论】:

  • 根据 RFC 6265,= 字符允许在 cookie 值中使用(第 4.1.1 节)。它只是不允许作为键(这当然是有道理的)。所以Base64没问题。如果您想知道“哪个 RFC”,这似乎是一个。

标签: java http


【解决方案1】:

最新的 RFC 是 6265,它声明以前的 Cookie RFC 已过时。

以下是 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

因此:

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

  • 根本不能使用特殊字符,除了可以用双引号括住值。

  • 不能引用特殊字符。

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

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

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

简而言之,符合 RFC 6265 的字母就可以了。

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

【讨论】:

    【解决方案2】:

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

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

    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
                (
                '_'=>'/',
                '-'=>'+',
                )));
        }
    

    【讨论】:

      猜你喜欢
      • 2015-01-05
      • 2019-09-11
      • 2021-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-09
      • 2016-03-26
      • 1970-01-01
      相关资源
      最近更新 更多