2011-07-07 129 views
12

虽然这是可能在C#中:(用户是L2S类在这种情况下)如何将对象存储在cookie中?

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是否安全?

回答

10

Cookie只是字符串数据;唯一的方法是将其序列化为一个字符串(xml,json,任意二进制的base-64,无论如何),但是,如果它涉及安全信息,您不应该信任任何其他的cookie。 “我是谁?”)作为:最终用户很容易改变它,而且b:你不希望每一个请求都带来任何大的开销。

IMO,将此作为服务器缓存是正确的;不要把它放在饼干里。

+0

所以我应该使用缓存的一个基本的记得我的选择吗? – Shaokan

+1

@Shaokan绝对;这可能是“会话”或更基本的缓存。但它不需要去客户端。所有的客户端需求都是一些随机令牌。 –

+0

所以基本上如果每个用户都有一个在注册时创建的guid,并且如果我将该guid存储在cookie中以记住用户,那会是一种安全的方法吗? – Shaokan

4

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

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

0

尝试这样?

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

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

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

btw:不要忘记,二进制可以编码为文本,如果你真的需要的话。

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

0

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

9

您可以使用JSON

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

是最佳选择。我使用Newtonsoft.Json。请记住,当使用回调时:var s = HttpContext.Current.Server.UrlDecode(cookie.Values [“myObjectKey”]。ToString()); – harveyt

+0

是的,请使用Netwonsoft.Json。我只想用标准库做出简单的回答。 –

0
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); 
0

你可以试试这个:

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); 
     } 

    } 
0

一个对象存储在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"; 
} 
+0

添加一点解释来回答主(晚)将比复制/通过代码片段更有帮助。 –

+0

如果你不知道阅读C#代码,这并不意味着你应该downvote,亲爱的马赫Abuthraaaaaaaa –

+0

感谢您更新您的答案。我没有让你失望。你的代码相对比较长,而且没有记录..我不知道它是否会回答这个问题。也对我来说,代码只被认为是低质量的答案:-) –

0

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; 
     } 

    } 
相关问题