Reprint: Elaborate cookie

Source: Internet
Author: User
Tags tojson converto

Elaborate cookies

Reprint: http://www.cnblogs.com/fish-li/archive/2011/07/03/2096903.html

Read Catalogue

    • Begin
    • Cookie Overview
    • The process of writing and reading cookies
    • Use cookies to save complex objects
    • Read and write cookies in JS
    • The application of cookies in session
    • The application of cookie in authentication
    • Security Status of Cookies
    • How to use cookies in a request sent by C #
    • Summary of refactoring and use
    • Add

Although a cookie is a very simple thing, it is a very important source of client data in Web development, and it can achieve a very good extensibility of the session state, so I think every web developer needs to have a clear understanding of it. This article will be a comprehensive description of the topic of cookies, but also a summary of my understanding of the cookie.

Back to Top Cookie overview

What is a cookie? a Cookie is a small piece of textual information that accompanies a user request and the page is passed between the WEB server and the browser. A Cookie contains information that a WEB application can read every time a user accesses a site.

Why do I need cookies? because the HTTP protocol is stateless, the Web server cannot differentiate whether it originates from the same browser for multiple requests made by a single browser. Therefore, additional data is required for the maintenance session. The Cookie is exactly the extra data that is passed along with the HTTP request.

what can a cookie do? A cookie is just a piece of text, so it can only hold strings. and the browser has a size limit on it and it will be sent to the server with each request, so it should be guaranteed not to be too large. The content of the cookie is also stored in plaintext, and some browsers provide an interface modification, so it is not appropriate to store important or privacy-related content.

restrictions on cookies. most browsers support a maximum of 4096 bytes of cookies. Because this limits the size of cookies, it is best to use cookies to store small amounts of data, or to store identifiers such as user IDs. The user ID can then be used to identify the user and to read user information from a database or other data source. The browser also restricts the number of cookies that the site can store on the user's computer. Most browsers allow only 20 cookies per site, and if you try to store more cookies, the oldest cookie is discarded. Some browsers also impose an absolute limit on the total number of cookies they will accept from all sites, typically 300.

From the previous content, we learned that the cookie is used to maintain the server session state, usually written by the server, in subsequent requests, for the server to read. The following article will follow this procedure to see how a cookie is written from the server, finally how it is uploaded to the server, and how it is read.

Back to the top of the cookie writing and reading process

In ASP. NET, the read-write cookie is done by using the HttpCookie class, which is defined as follows:

public sealed class httpcookie{//Gets or sets the domain that this Cookie is associated with.    The default value is the current domain.    public string Domain {get; set;}    Gets or sets the expiration date and time of this Cookie (on the client).    Public DateTime Expires {get; set;}    Gets a value indicating whether the Cookie has child keys.    public bool HasKeys {get;}    Gets or sets a value that specifies whether the Cookie can be accessed through client script. True if the Cookie has the HttpOnly attribute and cannot be accessed through client script; otherwise false.    The default is False.    public bool HttpOnly {get; set;}    Gets or sets the name of the Cookie.    public string Name {get; set;} Gets or sets the virtual path to be transferred with the current Cookie.    The default value is the path of the current request.    public string Path {get; set;}    Gets or sets a value that indicates whether the Cookie is transmitted using Secure Sockets Layer (SSL) (that is, HTTPS only).    public bool Secure {get; set;} Gets or sets a single Cookie value.    The default value is a null reference.    public string Value {get; set;}    Gets a collection of key-value pairs contained by a single Cookie object.    Public NameValueCollection Values {get;}    Gets the shortcut to the System.Web.HttpCookie.Values property. public string this[string key] {get; set;}} 

cookies are written to the browser : We can use the following code to write a cookie in the ASP and send it to the client's browser (for the sake of simplicity I have not set other properties).

HttpCookie cookie = new HttpCookie ("Mycookiename", "string value"); RESPONSE.COOKIES.ADD (cookie);

I think a lot of people have written similar code, but have you ever wondered how cookies are sent to the client at the end? Let's open the Fiddler and have a look.

From, you should be able to discover that the cookies we write on the server end up being sent to the client through the HTTP response header. Each write action produces a "Set-cookie" response header.
It is the browser that checks these headers to receive cookies after each request response.

the process of obtaining a cookie from ASP : We can use the following code to read a cookie in an ASP.

HttpCookie cookie = request.cookies["Mycookiename"];if (cookie! = null)    Labcookie1.text = cookie. Value;else    labcookie1.text = "undefined";

The code is also very simple, or a similar question: Have you ever wondered how cookies are uploaded to the server? Let's continue using Fiddler to find the answer.

From the picture, we can find that the cookie is placed in the request header and sent to the server. If you refresh the page all the time, you will find that every HTTP request, the cookie will be sent. of course, the browser does not send all the cookies it receives, it checks the domain name and directory currently being requested, as long as the two items match the domain and path that the cookie corresponds to. For domain, it is based on the principle of tail matching.
Therefore, when I visit www.cnblogs.com, the browser does not send out the cookies I receive when I browse www.163.com.

Delete Cookie: In fact, when you write a cookie, set expires to a "time earlier than the present time". That is: Set this cookie to expire and delete it when the browser receives the cookie.

HttpCookie cookie = new HttpCookie ("Mycookiename", null); Expires = new DateTime (1900, 1, 1); RESPONSE.COOKIES.ADD (cookie);
Back to top use cookies to save complex objects

The preceding example code roughly demonstrates the read and write operation of the cookie. However, we may want to save more complex "custom types" through cookies, so how do we do that? For this problem, we define a type to look at how to handle.

public class Displaysettings {public    int Style;    public int Size;        public override string ToString ()    {        return string. Format ("Style = {0}, Size = {1}", this.) Style, this. Size);    }    }

The above code, I define a type that is used to save the user's display settings when they browse the page. Next, I'll show you two ways to save and read them in a cookie.

Method-1, classic procedure. (Note the last two members of the HttpCookie definition code given earlier)

private void writecookie_2a () {    displaysettings setting = new Displaysettings {Style = 1, Size = n};    HttpCookie cookie = new HttpCookie ("DISPLAYSETTINGS1");    cookie["Style"] = setting. Style.tostring ();    cookie["Size"] = setting. Size.tostring ();    RESPONSE.COOKIES.ADD (cookie);} private void readcookie_2a () {    HttpCookie cookie = request.cookies["DISPLAYSETTINGS1"];    if (cookie = = null)        Labdisplaysettings1.text = "undefined";    else {        displaysettings setting = new Displaysettings ();        Setting. style = cookie["style"]. Trytoint ();        Setting. Size = cookie["Size"]. Trytoint ();        Labdisplaysettings1.text = setting. ToString ();    }}

Method-2 to serialize the object JSON to a string.

private void writecookie_2b () {    displaysettings setting = new Displaysettings {Style = 2, Size = n};    HttpCookie cookie = new HttpCookie ("DisplaySettings2", setting. ToJson ());    RESPONSE.COOKIES.ADD (cookie);} private void readcookie_2b () {    HttpCookie cookie = request.cookies["DisplaySettings2"];    if (cookie = = null)        Labdisplaysettings2.text = "undefined";    else {        displaysettings setting = cookie. Value.fromjson<displaysettings> ();        Labdisplaysettings2.text = setting. ToString ();    }}

This code uses the two extension methods I've defined.

For these two methods, I personally prefer the latter because it has better extensibility: If the type adds a member, you do not need to modify the code that reads and writes the cookie.
However, some of the characters produced in this way, such as "double quotes", are not supported by a very small number of browsers (Opera), so it is necessary to do urlencode or Base64 encoding processing.
Similarly, for the first method, we also need to do urlencode or BASE64 encoding when we encounter value with "double quotes".

Back to the top JS read and write cookies

Cookies are not only read and written on the server, they can also be read and written in the client's browser. And the cookie created in JS is still valid for the server (visible), next we look at how to write a cookie in JS, the demo code will create a button, and write a cookie when the button is clicked

<input type= "button" onclick= "Writecookie ();" Value= "Writecookie"/><script type= "Text/javascript" >    function Writecookie () {        var cookie = "cookie_js=22222222; path=/";        Document.cookie = cookie;    }    </script>

It is very simple to write a cookie in JS, as long as you assign a cookie string to Document.cookie, as for the format, you can refer to the results previously seen with fiddle.

Let's look at how to use JS to read cookies. Please refer to the following code:

<input type= "button" onclick= "Readcookie ();" Value= "Readcookie"/><script type= "Text/javascript" >    function Readcookie () {        alert (document.cookie);    }    </script>

Still visit Document.cookie, but this time we get all the cookie values, each key/value is separated by semicolons, and the middle is separated by an equal sign. Therefore, if you want to read the cookie in JS, be sure to follow this rule to split and parse the cookie you want to read. Since this is a bit cumbersome, we can jquery.cookie.js plug-ins to do this easily, interested friends can also see how it is handled. This plug-in code is relatively small, this is directly posted,

Note: Before we see the HttpCookie has a HttpOnly property, if it is true, then JS is not read that cookie, that is to say: if we generate cookies on the server does not want to be accessed in JS, can write a cookie, Set this property. However, with some tools, you can still see them.

Next, let's look at the application of the cookie in ASP.

Back to top the application of the cookie in the session

In ASP. HttpContext, the Page object has a session object that we can use to conveniently store some session-related information on the server.
As we mentioned earlier, theHTTP protocol is stateless, and for multiple requests made by a single browser, the Web server cannot differentiate whether it originated from the same browser. therefore, in order to implement a session, the server needs a session ID to be saved to the browser, so that it will be on subsequent requests with the session ID, so that the server can know which session a request belongs to, so that the state data related to the meeting session is maintained. Because cookies are invisible to the user, and each request is delivered to the server, it is an ideal storage container for the session ID. In ASP. NET, the default is to use a cookie to save the ID. Note: Although ASP. NET 2.0 also supports non-cookie-free sessions, there are drawbacks to modifying URLs in that way, so this approach is not widely used. This article will not do too much analysis of this topic, this way skip the cookie-free session.

Let's take a look at how the session uses a cookie to save the conversation ID, which, in the default ASP. config, has the following definition:

<sessionstate mode= "InProc" cookiename= "Asp.net_sessionid" cookieless= "UseCookies" ></sessionState>

If we perform the following actions:

session["Key1"] = DateTime.Now;

At this point, we can use some browser-provided tools to view the current cookie situation.

From the picture, the name of this cookie is the name we indicated in the configuration file, we can modify the configuration file:

<sessionstate cookiename= "SK" ></sessionState>

Then perform the above write session and look at the cookie

We can see that the SK cookie appears. Description: At the time I deleted the cookie named "Asp.net_sessionid".

From the above example, we can conclude that the session implementation is related to the cookie, and the server needs to save the conversation ID to the cookie.
Once again, unless you are using a cookie-free session mode, the session will require cookie support. In turn, cookies do not require session support.

Back to top the application of the cookie in authentication

I think a lot of people have used form identity authentication in the development of ASP. For a user request, we can easily determine on the server whether it represents a logged-on user.

This.labStatus.Text = (request.isauthenticated? "Logged in": "Not logged in");

So, have you ever wondered how ASP. NET identifies a request as being initiated by a logged-on user? Speaking of which, we are going to start with the user login. In order to implement the login and form authentication method, we need the following configuration:

<authentication mode= "Forms" >    <forms name= "UserStatus" ></forms></authentication>

Next, we need to implement the user login logic. There are many implementations, but the final call is similar, as shown in the following code:

private void Setlogin () {    System.Web.Security.FormsAuthentication.SetAuthCookie ("fish", false);}

As long as the above code is executed, we can see that the previous judgment "request.isauthenticated" returns True and "logged in" will eventually be displayed. To explore the secret, let's take a look at the cookie situation on the current page.

Sure enough, come up with a cookie with the same name as the name I specified in the configuration file. Let's take a look at what it looks like if you log off your current login:

private void Setlogout () {    System.Web.Security.FormsAuthentication.SignOut ();}

See, the cookie named "UserStatus" is missing. At this point, if you look at "request.isauthenticated" again, you can see that it returns false at this time. Alternatively, you can try again, after logging in, directly delete the cookie named "UserStatus", or you can find that the login status will show "not logged in." Perhaps, you're still a little unclear before I call "System.Web.Security.FormsAuthentication.SetAuthCookie (" fish ", false);" The answer to this question is simple: use Reflector.exe to see the implementation of ASP.
Here in order to make it more convincing that you are logged in with a cookie, I will create a cookie directly to see if ASP is able to recognize the cookie I created and that the login is valid. Please look at the code:

private void Setlogin () {    //system.web.security.formsauthentication.setauthcookie ("fish", false);    The following code is equivalent to the above code.    FormsAuthenticationTicket ticket = new FormsAuthenticationTicket (        2, "Fish", DateTime.Now, DateTime.Now.AddDays (30d), False, String. Empty);    String str = Formsauthentication.encrypt (ticket);    HttpCookie cookie = new HttpCookie (formsauthentication.formscookiename, str);    RESPONSE.COOKIES.ADD (cookie);}

If you execute this code, you will find: "request.isauthenticated" returns True, and the login status displays "logged in."
At this point, we can conclude that form authentication relies on cookie,asp.net to check the cookie name that we specify in the configuration file and decrypt the cookie to determine the login status of the current requesting user.

Back to top cookie security status

From the tablets, you should be able to find: The browser can provide some interface for users to clearly observe the cookies we write on the server, and even some browsers provide a convenient modification function. As shown in the following:

Therefore, when we write code on the server to read the cookie, especially when it involves type conversion, deserialization, or decryption, it is important to note that these operations are likely to fail. It also clearly reflects the fact that the values in the cookie are "at a glance" and can be seen by anyone. Therefore, we try not to store some important or sensitive content directly in the cookie. If we do need to use cookies to preserve some important content, but do not want to be understood by others, we can use some encryption methods to protect the content.

1. For some of the less important content , we can use simple processing methods such as Base64 to deal with.

2. For content with a relatively high level of importance , we can use some of the cryptographic tool classes provided by. NET to design encryption methods to protect them. However, cryptography and cryptographic decryption are not very simple algorithms, so the encryption method that you design may not be very secure.

3. Important content , we can use the formsauthenticationticket,formsauthentication provided by. NET to encrypt. I think this method is still relatively safe. After all, as we have seen before, the form identity authentication of ASP. NET is used to encrypt the identity of user login, so if this method is unsafe, it means that the identity authentication of ASP is not secure. If you use this method to encrypt, then please note: It produces the encrypted text is still relatively large, I also mentioned earlier, each request, the browser will be with the request to match all the cookies, so this cookie will have a certain impact on the transmission performance, so, please use carefully, Remember not to use too much.

Here's to add: Last year there was a "Padding Oracle Attack" topic, some people even mistakenly think that the ASP is not safe! If that's what you think, then take a look at this article: talking about the padding Oracle attack related content of this ASP to eliminate this error. Of course, we can also get some benefit from this topic: When decryption fails, do not give too many hints, when there is no such cookie exists.

Back to the top how to use cookies in C # requests

We've been talking about the server and the browser using cookies, in fact, the browser is also a common application, the. NET Framework also provides some classes can let us directly initiate HTTP requests, let's look at how to use the request in C # requests for cookies, In fact, it is very simple, mainly using the Cookiecontainer class, please see the following demo code:

private static string Sendhttprequestget (string url, Encoding Encoding, Cookiecontainer cookiecontainer) { if (string.        IsNullOrEmpty (URL)) throw new ArgumentNullException ("url");        if (encoding = = null) throw new ArgumentNullException ("encoding");        HttpWebRequest request = (HttpWebRequest) webrequest.create (URL); Request.        Method = "GET"; Request.                Cookiecontainer = Cookiecontainer; using (WebResponse response = Request. GetResponse ()) {using (StreamReader reader = new StreamReader (response. GetResponseStream (), encoding) {return reader.            ReadToEnd ();        }}} private void Sendhttpdemo () {StringBuilder sb = new StringBuilder ();        Cookiecontainer Cookiecontainer = new Cookiecontainer ();        String url = "Http://www.taobao.com";        Sendhttprequestget (URL, Encoding.default, cookiecontainer);   You can continue to initiate an HTTP request later, which will contain the last cookie written from the server     Sendhttprequestget ("Other URLs under the same domain name", encoding.default, Cookiecontainer);        At this point, we can show which cookies have been obtained cookiecollection cookies = cookiecontainer.getcookies (new Uri (URL)); if (cookie = null) {foreach (System.Net.Cookie Cookie in cookies) sb. Appendline (cookies.        ToString ()); } Txtcookies.text = sb.    ToString (); }
Back to top refactoring and usage summary

In the previous ASP. NET sample code, I have been using the HttpCookie class provided by the. NET to manipulate cookies in order to demonstrate the use of cookies in the original way, which is a bit repetitive and cumbersome, I've provided a few simple ways to make it easier to use cookies and a summary of how cookies are used.

<summary>///extension Tool class for convenient use of cookies///</summary>public Static class cookieextension{//We can write for some types of high frequency    The "read" Method of the door///<summary>///Read the string value from a cookie. </summary>//<param name= "cookies" ></param>//<returns></returns> public STA        Tic String GetString (this HttpCookie cookie) {if (cookie = = null) return null; Return cookie.    Value;    }///<summary> read Int value from a cookie.     </summary>//<param name= "cookies" ></param>//<param name= "Defaultval" ></param>  <returns></returns> public static int ToInt (this HttpCookie cookie, int defaultval) {if (        Cookie = = null) return defaultval; Return cookie.    Value.trytoint (Defaultval); }///<summary>///Read the value from a cookie and turn it into the specified type///</summary>//<typeparam name= "T" ></typepa ram>//<param name= "Cookie" ></param>//<returns></returns> public static T converto<t> (this HttpCookie cookie) {        if (cookie = = null) return to default (T); Return (T) Convert.changetype (cookie.    Value, typeof (T)); }///<summary>///Read the "JSON string" value from a cookie and deserialize it into an object for reading complex objects///</summary>//<typeparam Nam E= "T" ></typeparam>//<param name= "cookies" ></param>//<returns></returns> Pub        Lic static T fromjson<t> (this HttpCookie cookie) {if (cookie = = null) return to default (T); Return cookie.    Value.fromjson<t> (); }///<summary>//write an object to a cookie////</summary>//<param name= "obj" ></param>// /<param name= "name" ></param>///<param name= "expries" ></param> public static void Writecoo Kie (This object obj, string name, DateTime expries) {if (obj = = null) throw nEW ArgumentNullException ("obj"); if (string.                IsNullOrEmpty (name)) throw new ArgumentNullException ("name"); HttpCookie cookie = new HttpCookie (name, obj.        ToString ()); if (expries. HasValue) cookies. Expires = expries.        Value;    HTTPCONTEXT.CURRENT.RESPONSE.COOKIES.ADD (cookie); }///<summary>//delete the specified cookie///</summary>//<param name= "name" ></param> Publ IC static void Deletecookie (string name) {if (string.        IsNullOrEmpty (name)) throw new ArgumentNullException ("name");        HttpCookie cookie = new HttpCookie (name); Deleting a cookie is actually setting an "Expired Date" cookie.        Expires = new DateTime (1900, 1, 1);    HTTPCONTEXT.CURRENT.RESPONSE.COOKIES.ADD (cookie); }}

A more complete code can be obtained from the sample code in this article. (at the bottom of the article)

How to use:

public static class testclass{public    static void Write ()    {        string str = "China";        int AA =;        displaysettings setting = new Displaysettings {Style = 3, Size = n};        DateTime dt = new DateTime (1, 1, 0, 0);        Str. Writecookie ("Key1", DateTime.Now.AddDays (1d));        Aa. Writecookie ("Key2", null);        Setting. ToJson (). Writecookie ("Key3", null);        Dt. Writecookie ("Key4", null);    }    public static void Read ()    {        HttpRequest request = HttpContext.Current.Request;        String str = Request. cookies["Key1"]. GetString ();        int num = Request. cookies["Key2"]. ToInt (0);        displaysettings setting = Request. cookies["Key3"]. Fromjson<displaysettings> ();        DateTime dt = Request. cookies["Key4"]. Converto<datetime> ();    }    }

Note: The above code is used directly in the form of the string "Key", which may affect maintenance in the later stages of a larger program.
Therefore, it is suggested that the key used to access the cookie can have a uniform definition of a class, or that the read and write operations be packaged into attributes in a single class for unified management.

public static class cookievalues{    //recommends that cookie-related parameters be put together to provide Get/set properties (or methods) to access to avoid "key" everywhere writing public    static String AAA    {        get {return httpcontext.current.request.cookies["Key1"]. GetString (); }    } public    static int BBB    {        get {return httpcontext.current.request.cookies["Key2"]. ToInt (0); }    } public    static displaysettings CCC    {        get {return httpcontext.current.request.cookies["Key3"]. Fromjson<displaysettings> (); }    } public    static DateTime DDD    {        get {return httpcontext.current.request.cookies["Key4"]. Converto<datetime> (); }    }}
Back to the top of the supplement

Based on feedback from some friends, here are 4 additional things to keep in mind:

1. If you use form login verification and want to use cookies, it is recommended to set cookieless= "UseCookies" because the default value for this parameter is: cookieless= "UseDeviceProfile", ASP. NET may be misjudged. Dudu has suffered a loss.

<authentication mode= "Forms" >    <forms name= "Mycookiename" cookieless= "UseCookies" ></forms> </authentication>

2. Cookies have 3 properties, which we can generally use without setting, but their values can be specified in the Web. config default values:

3. While writing cookies, we can set properties other than name, value, but cannot read these settings when reading. In fact, in my sample code, I have forgotten the explanation.

4. HttpRequest.Cookies has something to do with httpresponse.cookies (it's strange).
The following code demonstrates this behavior:

protected void Page_Load (object sender, EventArgs e) {    DateTime.Now.ToString (). Writecookie ("T1", null);    Label1. Text = Showallcookies ();    Guid.NewGuid (). ToString (). Writecookie ("T2", null);    If you remove the following code, you will see 2 T1     Response.Cookies.Remove ("T1");    Response.Cookies.Remove ("T2");} private String Showallcookies () {    StringBuilder sb = new StringBuilder ();    for (int i = 0; i < Request.Cookies.Count; i++) {        HttpCookie cookie = request.cookies[i];        Sb. AppendFormat ("{0}={1}<br/>", cookies. Name, Cookie. Value);    }    Return SB. ToString ();}

The test code above will always show the T1 cookie, which will no longer be mapped.

All sample code for this article can be downloaded here.

Reprint: Elaborate cookie

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.