我知道还有其他问题,但他们似乎有一些假设而不是明确的答案。
我有限的理解是cookie值是:
还有其他“特殊”字符吗?
其他一些q / a建议一个base64对值进行编码,但这当然可能包括等于当然无效的等号。
我也看到了一些建议,可能会引用这些值,但会导致其他问题。
RFC 我读了一些RFC,包括许多cookie RFCS中的一些,但我仍然不确定是否存在对另一个RFC等的交叉引用,没有明确的简单解释或样本“回答”我的查询。
希望没有人会说阅读RFC,因为问题变成了哪个RFC ......
我想我也读过不同的浏览器规则略有不同,所以如果这很重要,请在答案中注明。
答案 0 :(得分:21)
最新的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的cookie值(但可以证明符合早期的RFC),您可能会发现cookie行为因浏览器而异。
简而言之,请遵守RFC 6265的字母,你应该没问题。
答案 1 :(得分:0)
提到了base64,所以这里是一个使用cookies的熟饼干解决方案。这些函数是关于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
(
'_'=>'/',
'-'=>'+',
)));
}