【问题标题】:How to store an object in a cookie?如何将对象存储在 cookie 中?
【发布时间】:2011-09-30 20:39:43
【问题描述】:

虽然这在 C# 中是可能的:(在此实例中,用户是 L2S 类)

User user = // function to get user
Session["User"] = user;

为什么这是不可能的?

User user = // function to get user
HttpCookie cookie = new HttpCookie();
cookie.Value = user; 

如何做到这一点?我不想将用户的 id 存储在 cookie 中,然后进行一些验证。

顺便说一句,如果可能的话,将对象存储在 cookie 中而不是仅存储 ID 是否安全?

【问题讨论】:

    标签: c# session object cookies store


    【解决方案1】:

    cookie 只是字符串数据;这样做的唯一方法是将其序列化为字符串(xml、json、base-64 的任意二进制文件等),但是,您不应该真的信任 cookie 中的任何内容,如果它与安全信息(“我是谁?”)相关,因为 a:最终用户可以轻松更改它,并且 b:您不希望每个请求都产生任何大的开销。

    IMO,将其缓存为服务器是正确的;不要把它放在 cookie 中。

    【讨论】:

    • 所以我应该使用缓存作为基本的记住我选项吗?
    • @Shaokan 绝对;这可能是“会话”,或更基本的缓存。但它不需要去客户端。客户需要的只是一些随机令牌。
    • 所以基本上如果每个用户都有一个在注册时创建的 guid,并且如果我将该 guid 存储在 cookie 中以记住用户,那是一种安全的方法吗?
    • @Shaokan - 是的。如果是为了完全登录,你应该使用正常的安全程序(可能是令牌/系列)
    • @marc 出于安全原因存储在 cookie 中的数据,您可以加密您的字符串然后将其存储在 cookie 中,显然您应该在从 cookie 中读取后解密以使用。
    【解决方案2】:

    你可以使用 JSON

    string myObjectJson = new JavaScriptSerializer().Serialize(myObject);
    var cookie = new HttpCookie("myObjectKey", myObjectJson) 
    {     
        Expires = DateTime.Now.AddYears(1) 
    };
    HttpContext.Response.Cookies.Add(cookie);
    

    【讨论】:

    • 是最好的选择。我使用 Newtonsoft.Json。记住retrive时使用: var s = HttpContext.Current.Server.UrlDecode(cookie.Values["myObjectKey"].ToString());
    • 是的,请使用 Netwonsoft.Json。我只想用标准库做一个简单的回答。
    【解决方案3】:

    简短的回答是:Cookie 存储字符串,而不是二进制对象。

    如果你真的想的话,你可以将你的对象序列化为字符串或 JSON。建议尽可能轻量级地保持数据来回。请记住:每次我们从浏览器与服务器通信时,您每次都在传递所有这些数据。

    【讨论】:

      【解决方案4】:

      您也可以加密这样的 cookie。那么内容(json/xml/etc)会更安全一些。 Marc 建议的服务器端缓存可能更好。

      权衡:增加网络流量(cookie 来回传递)与更大的服务器端内存占用和/或二级存储。

      顺便说一句:如果你真的需要,不要忘记二进制可以编码为文本。

      http://www.codeproject.com/KB/security/TextCoDec.aspx

      【讨论】:

        【解决方案5】:

        试试这样的?

        StringWriter outStream = new StringWriter();
        XmlSerializer s = new XmlSerializer(typeof(List<List<string>>));
        s.Serialize(outStream, myObj);
        cookie.Value = outStream.ToString();
        

        【讨论】:

          【解决方案6】:

          在 cookie 中,您可以存储字符串类型的值。您可以将对象存储到会话、视图状态或缓存中。但仍想存储在 cookie 中,只需使用 system.web.script.javascriptserialization 类并将整个对象转换为 json 字符串,然后将其存储在您的 cookie 中。

          【讨论】:

            【解决方案7】:
            System.Collections.Specialized.NameValueCollection cookiecoll = new System.Collections.Specialized.NameValueCollection();
            
                        cookiecoll.Add(bizID.ToString(), rate.ToString());
            
            
                    HttpCookie cookielist = new HttpCookie("MyListOfCookies");
                    cookielist.Values.Add(cookiecoll);
                    HttpContext.Current.Response.Cookies.Add(cookielist);
            

            【讨论】:

              【解决方案8】:

              你可以试试这个:

              public void AddToCookie(SessionUser sessionUser)
                  {
                      var httpCookie = HttpContext.Current.Response.Cookies["SessionUser"];
                      if (httpCookie != null)
                      {
                          httpCookie["ID"] = sessionUser.ID.ToString();
                          httpCookie["Name"] = sessionUser.Name;
                          httpCookie["Email"] = sessionUser.Email;
                          httpCookie["Phone"] = sessionUser.Phone;
                          httpCookie.Expires = DateTime.Now.AddDays(1);
                      }
              
                  }
              

              【讨论】:

                【解决方案9】:

                要将对象存储在 cookie 中,我们必须将其转换为限制为 4kb 的字符串化表示(压缩或未压缩)。此示例演示如何在 cookie 中保留一个小的“购买”对象(保存/延长/重置/清除)。而不是单独的代码行,我使用了一个 Json 来用一些数据填充这个对象。

                using System;
                using System.Collections.Generic;
                using System.Web;
                using Newtonsoft.Json;
                public class Customer
                {
                    public int id;
                    public string name;
                }
                public class Order
                {
                    public int id;
                    public decimal total;
                    public Customer customer;
                }
                public class OrderItem
                {
                    public int id;
                    public string name;
                    public decimal price;
                }
                public class Buy
                {
                    public Order order;
                    public List<OrderItem> cart;
                }
                static readonly string cookieName = @"buy";
                protected override void OnLoad(EventArgs e)
                {
                    base.OnLoad(e);
                    if (!IsPostBack)
                        Restore_Click(null, null);
                }
                protected void Save_Click(object sender, EventArgs e)
                {
                    string buy = JsonConvert.SerializeObject(new
                    {
                        order = new
                        {
                            id = 1,
                            total = 20.10,
                            customer = new
                            {
                                id = 1,
                                name = "Stackoverflow"
                            }
                        },
                        cart = new[] {
                            new {
                                id = 1 , 
                                name = "Stack",
                                price = 10.05 
                            },
                            new {
                                id = 2 , 
                                name = "Overflow",
                                price = 10.05 
                            }
                        }
                    });
                    HttpContext.Current.Response.Cookies.Add(
                        new HttpCookie(cookieName, buy) {
                            Expires = DateTime.Now.AddDays(7)
                        }
                    );
                    StatusLabel.Text = "Saved";
                }
                protected void Prolong_Click(object sender, EventArgs e)
                {
                    HttpCookie cookie = HttpContext.Current.Request.Cookies[cookieName];
                    if (cookie != null)
                    {
                        cookie.Expires = DateTime.Now.AddDays(7);
                        HttpContext.Current.Response.Cookies.Add(cookie);
                        StatusLabel.Text = "Prolonged";
                    }
                    else StatusLabel.Text = "Not prolonged - expired";
                }
                protected void Restore_Click(object sender, EventArgs e)
                {
                    Buy buy = null;
                    HttpCookie cookie = HttpContext.Current.Request.Cookies[cookieName];
                    if (cookie != null)
                    {
                        buy = JsonConvert.DeserializeObject<Buy>(cookie.Value);
                        StatusLabel.Text = "Restored";
                    }
                    else StatusLabel.Text = "Not restored - expired";
                }
                protected void ClearOut_Click(object sender, EventArgs e)
                {
                    HttpCookie cookie = HttpContext.Current.Request.Cookies[cookieName];
                    if (cookie != null)
                    {
                        cookie.Expires = DateTime.Now.AddMonths(-1);
                        HttpContext.Current.Response.Cookies.Add(cookie);
                        StatusLabel.Text = "Cleared out";
                    }
                    else StatusLabel.Text = "Not found - expired";
                }
                

                【讨论】:

                • 在回答 main (late) 时添加一点解释将比复制/粘贴代码 sn-p 更有帮助。
                • 如果您不会阅读 c# 代码,这并不意味着您应该投反对票,亲爱的 Maher Abuthraaaaaaaaa
                • 感谢您更新您的答案。我没有对你投反对票。您的代码相对较长并且没有记录..我不知道它是否会回答这个问题..对我来说仅代码被认为是低质量的答案:-)
                【解决方案10】:

                Cookie 仅存储字符串。 你可以做什么:

                 var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
                 var json = serializer.Serialize(user);
                controller.Response.SetCookie(
                        new HttpCookie({string_name}, json)
                        {
                            Expires = false // use this when you want to delete
                                    ? DateTime.Now.AddMonths(-1)
                                    : DateTime.Now.Add({expiration})
                        });
                

                这应该将整个对象插入 cookie。

                为了从cookie中读回一个对象:

                    public static {Object_Name} GetUser(this Controller controller)
                    {
                
                        var httpRequest = controller.Request;
                
                        if (httpRequest.Cookies[{cookie_name}] == null)
                        {
                            return null;
                        }
                        else
                        {
                            var json = httpRequest.Cookies[{cookie_name}].Value;
                            var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
                            var result = serializer.Deserialize<{object_name}>(json);
                            return result;
                        }
                
                    }
                

                【讨论】:

                  猜你喜欢
                  • 2023-03-31
                  • 2023-03-15
                  • 1970-01-01
                  • 2012-02-20
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2010-12-19
                  • 2020-12-09
                  相关资源
                  最近更新 更多