web-dev-qa-db-fra.com

Comment stocker un objet dans un cookie?

Bien que cela soit possible en C #: (l'utilisateur est une classe L2S dans ce cas)

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

pourquoi ce n'est pas possible?

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

et comment peut-il être fait? Je ne souhaite pas stocker l'identifiant de l'utilisateur dans le cookie, puis procéder à une validation.

Au fait, si possible, est-il sécurisé de stocker un objet dans un cookie plutôt que seulement son identifiant?

14
Shaokan

Un cookie est juste une chaîne de données; la seule façon de le faire serait de le sérialiser en tant que chaîne (xml, json, base 64 en binaire arbitraire, peu importe), cependant, vous ne devriez pas vraiment ne faire confiance à rien dans un cookie s'il est lié à la sécurité informations ("qui suis-je?") en tant que a: il est facile pour l'utilisateur final de la modifier, et b: vous ne voulez pas des frais généraux conséquents pour chaque requête.

Messagerie Internet uniquement, la mise en cache en tant que serveur est la bonne chose; ne mettez pas cela dans un cookie.

11
Marc Gravell

Vous pouvez utiliser JSON

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

La réponse courte est: Les cookies stockent des chaînes et non des objets binaires.

Vous pouvez sérialiser votre objet en chaînes ou en JSON si vous le souhaitez vraiment. Suggérez de garder les données aussi légères que possible. Rappelez-vous: chaque fois que nous communiquons du navigateur au serveur, vous transmettez toutes les données à chaque fois.

4
p.campbell

vous pouvez également chiffrer un tel cookie. Le contenu (json/xml/etc) serait alors un peu plus sûr. La mise en cache côté serveur, comme le suggère Marc, est probablement meilleure.

Compromis: augmentation du trafic sur le réseau (les cookies sont échangés) Vs empreinte mémoire plus importante côté serveur et/ou stockage en mémoire secondaire.

au fait: n'oubliez pas que le binaire peut être encodé en texte si vous en avez vraiment besoin.

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

1
sgtz

Essayer quelque chose comme ça?

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

vous pouvez essayer ceci:

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
Cute Teddy

dans le cookie, vous pouvez stocker une valeur de type chaîne. vous pouvez stocker votre objet en session, viewstate ou en cache. mais vous souhaitez tout de même stocker dans les cookies, utilisez simplement la classe system.web.script.javascriptserialization et convertissez l'objet entier en chaîne json, puis enregistrez-le dans votre cookie.

0
Sonu
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
Ankita Singh

pour stocker un objet dans un cookie, nous devons le convertir en présentation sous forme de chaîne (compressée ou non), limitée à 4 Ko. Cet exemple montre comment conserver un petit objet "Acheter" dans un cookie (enregistrer/prolonger/réinitialiser/effacer). au lieu de lignes de code distinctes, j'ai utilisé un Json pour remplir cet objet avec des données.

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

Cookie Store uniquement des chaînes. Ce que tu peux faire:

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

Cela devrait insérer l'objet entier à cookie.

Pour lire le cookie dans un objet:

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

    }
0
Igal C