如何在cookie中安全地存储Unicode字符



我使用cookie在搜索页面中显示一些数据,但我的cookie在使用Unicode字符时会混淆值。例如,当我存储Inglês时,当我读回它时,我得到的是Inglês

这就是我保存cookie的方式:

public void SalvaValue(string sessionKey, string sessionValue)
{
    Response.Cookies.Add(new HttpCookie(sessionKey));
    var httpCookie = Response.Cookies[sessionKey];
    if (httpCookie != null) httpCookie.Value = sessionValue;
    if (httpCookie != null) httpCookie.Expires = DateTime.Now.AddDays(14);
}

这就是我检索它的方式:

if (Request.Cookies["BuscaTipo"] != null)
{
    tipoBusca = Request.Cookies["BuscaTipo"].Value.ToString();
     var cookie = new HttpCookie("BuscaTipo") { Expires = DateTime.Now.AddDays(-1) };
     Response.Cookies.Add(cookie);
}

当我调试站点时,它在设置时会在代码中显示正确的值,但在我使用jQuery执行请求后,该值会出现错误的字符。

如何在cookie中安全地存储Unicode字符?

请参阅如何将其他语言(unicode)存储在Cookie中并重新获取,unicode Cookie值,如何使用HTTP标头发送非英语unicode字符串?和允许在cookie中使用字符,以解释为什么需要对cookie值进行编码。

简言之:大多数浏览器都支持头文件中的Unicode字符(发送cookie),但并非所有浏览器都支持。一些浏览器将Unicode字节解释为ASCII,从而产生Mojibake。

jQuery似乎也在一些相关问题中发挥了作用,但我无法重现。

因此,为了在所有浏览器中安全地存储Unicode字符(或者任何非ASCII或控制字符),您需要对字符进行编码。这可以通过例如base64和百分比编码来实现。

后者的实现,稍微改编自Cookie和Unicode字符:

public static class CookieExtensions
{
    public static string DecodedValue(this HttpCookie cookie)
    {
        if (cookie == null)
        {
            throw new ArgumentNullException("cookie");
        }
        return HttpUtility.UrlDecode(cookie.Value);
    }
    public static void SetEncodedValue(this HttpCookie cookie, string value)
    {
        if (cookie == null)
        {
            throw new ArgumentNullException("cookie");
        }
        cookie.Value = HttpUtility.UrlEncode(value);
    }
    public static string DecodedValues(this HttpCookie cookie, string name)
    {
        if (cookie == null)
        {
            throw new ArgumentNullException("cookie");
        }
        return HttpUtility.UrlDecode(cookie.Values[name]);
    }
    public static void SetEncodedValues(this HttpCookie cookie, string name, string value)
    {
        if (cookie == null)
        {
            throw new ArgumentNullException("cookie");
        }
        cookie.Values[name] = HttpUtility.UrlEncode(value);
    }
    public static string DecodedValues(this HttpCookie cookie, int index)
    {
        if (cookie == null)
        {
            throw new ArgumentNullException("cookie");
        }
        return HttpUtility.UrlDecode(cookie.Values[index]);
    }
}

用法:

if (Request.Cookies["TestCookieValue"] != null)
{
    ViewBag.CookieValue = Request.Cookies["TestCookieValue"].DecodedValue();
}
if (Request.Cookies["TestCookieValues"] != null)
{
    ViewBag.CookieValues = Request.Cookies["TestCookieValues"].DecodedValues("foo");
    ViewBag.CookieValuesIndexed = Request.Cookies["TestCookieValues"].DecodedValues(0);
}
var cookieWithValue = new HttpCookie("TestCookieValue");
cookieWithValue.Expires = DateTime.Now.AddHours(1);
cookieWithValue.SetEncodedValue("Inglês");
Response.SetCookie(cookieWithValue);
var cookieWithValues = new HttpCookie("TestCookieValues");
cookieWithValues.Expires = DateTime.Now.AddHours(1);
cookieWithValues.SetEncodedValues("foo", "Inglês");
Response.SetCookie(cookieWithValues);

请注意,HttpUtility.UrlDecode()是危险的,请使用AntiXSS来防止cookie值中的跨站点脚本和SQL注入,这些值可以由客户端任意设置。

您也可能会重新考虑将Unicode值存储在cookie中。您可以很容易地以其他方式识别语言,例如通过代码en-US或其数据库索引(如果适用)。

最新更新