ASP. NET Cookie Overview
Cookie provides a way to store user-specific information in Web applications. For example, when a user accesses your site, you can use cookies to store user preferences or other information. When the user visits your website again, the application can retrieve the previously stored information.
What is Cookie?
Cookie is a short text message that is transmitted between the Web server and the browser as user requests and pages. Cookie contains information that can be read by Web applications every time a user accesses the site.
For example, if the application sends a page to the user when the user requests the page in the site, it is not only a page, but also a Cookie containing the date and time, the user's browser obtains the Cookie while obtaining the page, and stores it in a folder on the user's hard disk.
Later, if the user requests the page on your site again, when the user enters the URL, the browser will find the Cookie associated with the URL on the local hard disk. If the Cookie exists, the browser sends the Cookie along with the page request to your site. Then, the application can determine the date and time of the user's last visit to the site. You can use this information to display a message to the user or check the expiration date.
Cookies are associated with websites rather than specific pages. Therefore, no matter which page on the site the user requests, the browser and server exchange Cookie information. When a user accesses different sites, each site may send a Cookie to the user's browser, which stores all the cookies separately.
Cookies help websites store information about visitors. In general, Cookie is a way to maintain the continuity of Web applications (that is, execution status management. Except for a short period of actual information exchange time, the browser and the Web server are disconnected. The Web server processes each request sent to the Web server separately. However, in many cases, it is very useful for Web servers to identify users on user request pages. For example, a Web server on a shopping site tracks each shopper so that the site can manage the shopping cart and other user-specific information. Therefore, Cookie can be used as a business card to provide relevant identification information to help the application determine how to continue execution.
Cookie can be used for multiple purposes, all of which are to help websites remember users. For example, a site that implements a public opinion test can simply use cookies as a Boolean value to indicate whether the user's browser has participated in the vote, so that the user cannot perform a second vote. Websites requiring users to log on can use cookies to record that users have logged on, so that users do not have to enter creden。 every time.
Cookie restrictions
Most browsers support a Cookie of up to 4096 bytes. Because this limits the Cookie size, it is best to use cookies to store a small amount of data or user IDs. User IDs can then be used to identify users and read user information from databases or other data sources. (For information about how to store user information security suggestions, see the "Cookie and security" section below .)
The browser also limits the number of cookies that the site can store on the user's computer. Most browsers only allow 20 cookies per site. If you try to store more cookies, the oldest cookies will be discarded. Some browsers impose absolute limits on the total number of cookies they will accept from all sites, typically 300.
The Cookie restriction you may encounter is that users can set their browsers to reject cookies. If you define an P3P Privacy Policy and place it in the root directory of the website, more browsers will accept the cookies of your site. However, you may have to discard cookies completely and store user-specific information through other mechanisms. The common method for storing user information is session status, but session status depends on Cookie, which is described in the "Cookie and session Status" section later.
Note:
For more information about Web application state management and options for saving information, see ASP. NET state management overview and ASP. NET state management recommendations.
Although cookies are very useful in applications, applications should not rely on the ability to store cookies. Do not use cookies to support key functions. If your application depends on cookies, you can test to determine whether the browser will accept cookies. See "check whether your browser accepts cookies" next to this topic.
Compile Cookie
The browser manages cookies in the user's system. Cookie is sent to the browser through the HttpResponse object, which is known as a set of Cookies. The HttpResponse object can be accessed as the Response attribute of the Page class. All cookies to be sent to the browser must be added to this collection. When creating a Cookie, you must specify the Name and Value. Each Cookie must have a unique name so that it can be recognized when being read from the browser. Because cookies are stored by name, naming two cookies with the same name causes one Cookie to be overwritten.
You can also set the Cookie expiration date and time. When a user accesses the website where the Cookie is written, the browser deletes the expired Cookie. As long as the application considers the Cookie value valid, the Cookie validity period should be set to this period. For cookies that never expire, you can set the expiration date to 50 years from now on.
Note:
Users can clear cookies on their computers at any time. Even if the stored Cookie has a long expiration date, you can still decide to delete all the cookies and clear all the settings stored in the Cookie.
If no Cookie validity period is set, a Cookie will still be created, but it will not be stored on the user's hard disk. The Cookie is maintained as part of the user's session information. When the user closes the browser, the Cookie is discarded. This kind of non-permanent Cookie is suitable for saving the information stored for a short period of time, or saving the information that should not be written to the disk on the client computer for security reasons. For example, if you are using a public computer and you do not want to write cookies to the disk of the computer, you can use non-permanent cookies.
You can add Cookies to Cookies in multiple ways. The following example shows two methods to compile a Cookie:
Copy codeThe Code is as follows: Response. Cookies ["userName"]. Value = "patrick ";
Response. Cookies ["userName"]. Expires = DateTime. Now. AddDays (1 );
HttpCookie aCookie = new HttpCookie ("lastVisit ");
ACookie. Value = DateTime. Now. ToString ();
ACookie. Expires = DateTime. Now. AddDays (1 );
Response. Cookies. Add (aCookie );
This example adds two Cookies to the Cookie set, one named userName and the other named lastVisit. For the first Cookie, the Cookie set value is directly set. You can add values to a set in this way, because Cookies are derived from a dedicated set of the NameObjectCollectionBase type.
For the second Cookie, the Code creates an HttpCookie-type object instance, sets its attributes, and adds it to the Cookie set through the Add method. When instantiating an HttpCookie object, the Cookie name must be passed as part of the constructor.
Both examples have completed the same task, that is, writing a Cookie to the browser. In the two methods, the validity period value must be of the DateTime type. However, the lastVisited value is also the datetime value. Because all Cookie values are stored as strings, The datetime value must be converted to String.
Multi-value Cookie
You can store a value in the Cookie, such as the user name and the last access time. You can also store multiple name/value pairs in one Cookie. The name and value are symmetric subkeys. (The Sub-key layout is similar to the query string in the URL .) For example, instead of creating two separate cookies named userName and lastVisit, you can create a Cookie named userInfo, which contains two subkeys: userName and lastVisit.
You may use the subkeys for multiple reasons. First, it is convenient to put related or similar information in a Cookie. In addition, because all information is in one Cookie, Cookie attributes such as validity period apply to all information. (If You Want To specify different expiration dates for different types of information, you should store the information in a separate Cookie .)
A Cookie with a sub-key can also help you limit the size of the Cookie file. As mentioned in the previous section "Cookie restrictions", cookies are generally limited to 4096 bytes, and each site can store up to 20 cookies. When a single Cookie with the BIND key is used, the number of cookies used will not exceed the limit of 20 cookies allocated to the site. In addition, a Cookie consumes about 50 characters of system overhead (used to save the validity period information, etc.), plus the length of the stored value, the total number of bytes is close to 4096 bytes. If five sub-keys are stored instead of five individual cookies, the system overhead of individual cookies can be saved by about 200 bytes.
To create a Cookie with the BIND key, you can use various syntaxes to compile a single Cookie. The following example shows two methods for compiling the same Cookie. Each Cookie has two subkeys:
Copy codeThe Code is as follows: Response. Cookies ["userInfo"] ["userName"] = "patrick ";
Response. Cookies ["userInfo"] ["lastVisit"] = DateTime. Now. ToString ();
Response. Cookies ["userInfo"]. Expires = DateTime. Now. AddDays (1 );
HttpCookie aCookie = new HttpCookie ("userInfo ");
ACookie. Values ["userName"] = "patrick ";
ACookie. Values ["lastVisit"] = DateTime. Now. ToString ();
ACookie. Expires = DateTime. Now. AddDays (1 );
Response. Cookies. Add (aCookie );
Control the Cookie range
By default, all cookies of a site are stored on the client together, and all cookies are sent to the server together with any requests sent to the site. That is to say, each page of a website can obtain all the cookies of the site. However, you can set the Cookie range in two ways:
Restrict the Cookie range to a folder on the server, which allows you to restrict the Cookie to an application on the site.
Set the range to a domain, which allows you to specify which subdomains in the domain can access cookies.
Restrict cookies to a folder or application
To restrict the Cookie to a folder on the server, set the Path attribute of the Cookie as follows:
Copy codeThe Code is as follows: HttpCookie appCookie = new HttpCookie ("AppCookie ");
AppCookie. Value = "written" + DateTime. Now. ToString ();
AppCookie. Expires = DateTime. Now. AddDays (1 );
AppCookie. Path = "/Application1 ";
Response. Cookies. Add (appCookie );
Note:
You can also write a Cookie by adding the Cookie directly to the Cookie set, as shown in the previous example.
The path can be a physical path under the root directory of the site or a virtual root directory. The result is that the Cookie can only be used for pages in the Application1 folder or virtual root directory. For example, if your site name is http://www.contoso.com/, the Cookie created in the previous example can only be used for pages that path to the http://www.contoso.com/Application1/ and all pages under the folder. However, Cookies cannot be used for pages in other applications, such as pages in http://www.contoso.com/Application2/ or http://www.contoso.com.
Note:
In some browsers, the path is case sensitive. You cannot control how users type URLs in their browsers, but if the application depends on cookies related to specific paths, make sure that the URL in all the hyperlinks you create matches the case of the Path property value.
Restrict the Cookie domain range
By default, cookies are associated with specific domains. For example, if your website is http://www.contoso.com/, then when a user requests a webpage from the site, the Cookie you prepared will be sent to the server. (This may not include cookies with specific path values .) If a site has subdomains (for example, contoso.com, sales.contoso.com, and support.contoso.com), you can associate cookies with specific subdomains. To perform this operation, set the Domain attribute of the Cookie, as shown in the following example:
Response. Cookies ["domain"]. Value = DateTime. Now. ToString ();
Response. Cookies ["domain"]. Expires = DateTime. Now. AddDays (1 );
Response. Cookies ["domain"]. Domain = "support.contoso.com ";
When the domain is set in this way, the Cookie can only be used for pages in the specified subdomain. You can also use the Domain attribute to create cookies that can be shared among multiple subdomains, as shown in the following example:
Copy codeThe Code is as follows: Response. Cookies ["domain"]. Value = DateTime. Now. ToString ();
Response. Cookies ["domain"]. Expires = DateTime. Now. AddDays (1 );
Response. Cookies ["domain"]. Domain = "contoso.com ";
Then, the Cookie can be used for the primary domain, or for the sales.contoso.com and support.contoso.com domains.
Read Cookie
When a browser sends a request to the server, the Cookie of the server is sent along with the request. In ASP. NET applications, you can use the HttpRequest object to read cookies. This object can be used as the Request attribute of the Page class. The structure of the HttpRequest object is basically the same as that of the HttpResponse object. Therefore, you can read cookies from the HttpRequest object in the same way as writing cookies to the HttpResponse object. The following code example demonstrates two methods. You can obtain the Cookie value named username through these two methods and display the value in the Label control:
Copy codeThe Code is as follows: if (Request. Cookies ["userName"]! = Null)
Label1.Text = Server. HtmlEncode (Request. Cookies ["userName"]. Value );
If (Request. Cookies ["userName"]! = Null)
{
HttpCookie aCookie = Request. Cookies ["userName"];
Label1.Text = Server. HtmlEncode (aCookie. Value );
}
Before trying to obtain the Cookie value, make sure that the Cookie exists. If the Cookie does not exist, an NullReferenceException will be returned. Note that you must call the HtmlEncode method to encode the Cookie content before displaying the Cookie content on the page. This prevents malicious users from adding executable scripts to cookies. For more information about Cookie security, see "Cookie and security.
Note:
Because different browsers store cookies in different ways, different browsers on the same computer do not need to be able to read each other's cookies. For example, if you use Internet Explorer to test a page and then use another browser for testing, the latter will not find the Cookie saved by Internet Explorer.
The method for reading the Cookie neutron key value is similar to that for setting this value. The following code example shows how to obtain the subkey value:
Copy codeThe Code is as follows: if (Request. Cookies ["userInfo"]! = Null)
{
Label1.Text =
Server. HtmlEncode (Request. Cookies ["userInfo"] ["userName"]);
Label2.Text =
Server. HtmlEncode (Request. Cookies ["userInfo"] ["lastVisit"]);
}
In the preceding example, the Code reads the value of the sub-key lastVisit, Which is previously set as a string representation of the DateTime value. Cookie stores the value as a string. Therefore, to use the lastVisit value as a date, you must convert it to an appropriate type, as shown in the following example:
DateTime dt;
Dt = DateTime. Parse (Request. Cookies ["userInfo"] ["lastVisit"]);
The subkeys in cookies are converted into NameValueCollection collections. Therefore, another way to obtain a single sub-key is to obtain the sub-key set and then extract the sub-key value by name, as shown in the following example:
Copy codeThe Code is as follows: if (Request. Cookies ["userInfo"]! = Null)
{
System. Collections. Specialized. NameValueCollection
UserInfoCookieCollection;
UserInfoCookieCollection = Request. Cookies ["userInfo"]. Values;
Label1.Text =
Server. HtmlEncode (UserInfoCookieCollection ["userName"]);
Label2.Text =
Server. HtmlEncode (UserInfoCookieCollection ["lastVisit"]);
}
Change Cookie expiration date
The browser is responsible for Cookie management, and the Cookie expiration time and date can help the browser manage Cookie storage. Therefore, although the Cookie name and value can be read, the Cookie expiration date and time cannot be read. When the browser sends Cookie information to the server, the validity period is not included. (The Cookie's Expires attribute always returns a datetime value of 0 .) If you are worried about the Cookie expiration date, you must reset the Cookie. This process is described in the "Modify and delete Cookie" section.
Note:
You can read the Expires attribute of the Cookie set in the HttpResponse object before sending the Cookie to the browser. However, you cannot obtain the validity period from the returned HttpRequest object.
Read Cookie set
Sometimes, you may need to read all the cookies available for the page. To read the names and values of all Cookies available for the page, you can use the following code to use Cookies in sequence.
Copy codeThe Code is as follows: System. Text. StringBuilder output = new System. Text. StringBuilder ();
HttpCookie aCookie;
For (int I = 0; I <Request. Cookies. Count; I ++)
{
ACookie = Request. Cookies [I];
Output. Append ("Cookie name =" + Server. HtmlEncode (aCookie. Name)
+ "<Br/> ");
Output. Append ("Cookie value =" + Server. HtmlEncode (aCookie. Value)
+ "<Br/> ");
}
Label1.Text = output. ToString ();
Note:
When running this code, you may see a Cookie named ASP. NET_SessionId. ASP. NET uses this Cookie to store the unique identifier of your session. Session cookies are not stored on your hard disk. For more information about session cookies, see the "Cookie and session Status" section after this topic.
The preceding example has a restriction: If a Cookie has a subkey, the subkey is displayed as a name/value string. You can read the HasKeys attribute of the Cookie to determine whether the Cookie has a subkey. If any, you can read the child key set to obtain the names and values of each child key. You can use the index value to directly read the sub-key value from the Values set. The corresponding sub-key name can be obtained from the AllKeys Member of the Values set. This member returns a string array. You can also use the Keys Member of the Values set. However, when you access the AllKeys attribute for the first time, the attribute is cached. In contrast, each time you access the Keys attribute, this attribute generates an array. Therefore, in the context of a single page request, the AllKeys attribute is much faster during subsequent access.
The following example shows how to modify the previous example. In this example, the HasKeys attribute is used to test whether a child key exists. If the child key is detected, the Child key is obtained from the Values set:
Copy codeThe Code is as follows: for (int I = 0; I <Request. Cookies. Count; I ++)
{
ACookie = Request. Cookies [I];
Output. Append ("Name =" + aCookie. Name + "<br/> ");
If (aCookie. HasKeys)
{
For (int j = 0; j <aCookie. Values. Count; j ++)
{
SubkeyName = Server. HtmlEncode (aCookie. Values. AllKeys [j]);
SubkeyValue = Server. HtmlEncode (aCookie. Values [j]);
Output. Append ("Subkey name =" + subkeyName + "<br/> ");
Output. Append ("Subkey value =" + subkeyValue +
"<Br/> ");
}
}
Else
{
Output. Append ("Value =" + Server. HtmlEncode (aCookie. Value) +
"<Br/> ");
}
}
Label1.Text = output. ToString ();
Alternatively, the sub-key can be extracted as a NameValueCollection object, as shown in the following example:
Copy codeThe Code is as follows: System. Text. StringBuilder output = new System. Text. StringBuilder ();
HttpCookie aCookie;
String subkeyName;
String subkeyValue;
For (int I = 0; I <Request. Cookies. Count; I ++)
{
ACookie = Request. Cookies [I];
Output. Append ("Name =" + aCookie. Name + "<br/> ");
If (aCookie. HasKeys)
{
System. Collections. Specialized. NameValueCollection CookieValues =
ACookie. Values;
String [] CookieValueNames = CookieValues. AllKeys;
For (int j = 0; j <CookieValues. Count; j ++)
{
SubkeyName = Server. HtmlEncode (CookieValueNames [j]);
SubkeyValue = Server. HtmlEncode (CookieValues [j]);
Output. Append ("Subkey name =" + subkeyName + "<br/> ");
Output. Append ("Subkey value =" + subkeyValue +
"<Br/> ");
}
}
Else
{
Output. Append ("Value =" + Server. HtmlEncode (aCookie. Value) +
"<Br/> ");
}
}
Label1.Text = output. ToString ();
Modify and delete cookies
You cannot directly modify the Cookie. The process of changing a Cookie involves creating a new Cookie with a new value, and then sending it to the browser to overwrite the old Cookie on the client. The following code example shows how to change the Cookie value that stores the number of user visits to the site:
Copy codeThe Code is as follows: int counter;
If (Request. Cookies ["counter"] = null)
Counter = 0;
Else
{
Counter = int. Parse (Request. Cookies ["counter"]. Value );
}
Counter ++;
Response. Cookies ["counter"]. Value = counter. ToString ();
Response. Cookies ["counter"]. Expires = DateTime. Now. AddDays (1 );
Deleting a Cookie (physically removing a Cookie from a user's hard disk) is a form of Cookie modification. The Cookie cannot be directly removed because it is on the user's computer. However, the browser can delete cookies for you. This technology creates a new Cookie with the same name as the Cookie to be deleted, and sets the Cookie expiration date to a date earlier than the current date. When the browser checks the Cookie expiration date, the browser will discard the expired Cookie. The following code example demonstrates how to delete all available cookies in an application:
Copy codeThe Code is as follows: HttpCookie aCookie;
String cookieName;
Int limit = Request. Cookies. Count;
For (int I = 0; I <limit; I ++)
{
CookieName = Request. Cookies [I]. Name;
ACookie = new HttpCookie (cookieName );
ACookie. Expires = DateTime. Now. AddDays (-1 );
Response. Cookies. Add (aCookie );
}
The method for modifying or deleting a subkey is the same as that for creating it, as shown in the following example:
Response. Cookies ["userInfo"] ["lastVisit"] = DateTime. Now. ToString ();
Response. Cookies ["userInfo"]. Expires = DateTime. Now. AddDays (1 );
To delete a single sub-key, you can operate on the Cookie's Values set, which is used to save the sub-key. First, obtain the Cookie from the Cookie object to recreate the Cookie. Then you can call the Remove Method of the Values set and pass the name of the sub-key to be deleted to the Remove Method. Then, add the Cookie to the Cookie set so that the Cookie will be sent back to the browser in the modified format. The following code example shows how to delete a subkey. In this example, the name of the child key to be removed is specified in the variable.
Copy codeThe Code is as follows: string subkeyName;
SubkeyName = "userName ";
HttpCookie aCookie = Request. Cookies ["userInfo"];
ACookie. Values. Remove (subkeyName );
ACookie. Expires = DateTime. Now. AddDays (1 );
Response. Cookies. Add (aCookie );
Cookie and security
The security issue of cookies is similar to that of obtaining data from clients. Cookie is another form of user input in applications, so it is easy for them to obtain and use cookies illegally. Because the Cookie is stored on your computer, you can at least view the data stored in the Cookie. You can change the Cookie before the browser sends it to you.
Do not store sensitive information in cookies, such as user names, passwords, and credit card numbers. Do not place any content in cookies that should not be controlled by users, or that may be controlled by others who steal cookies.
Similarly, do not trust the information obtained from cookies. Do not assume that the data is the same as when you write it out. The security measures used to process Cookie values should be the same as those used to process data typed by users on the webpage. The example above in this topic demonstrates how to encode the Cookie content in HTML before displaying the value on the page, which is the same as before displaying any information obtained from the user.
The Cookie is sent in plain text between the browser and the server. Anyone who can intercept Web communication can read the Cookie. You can set Cookie properties so that cookies can only be transmitted over connections using Secure Sockets Layer (SSL. SSL does not prevent the Cookies stored on users' computers from being read or operated. However, it prevents the cookies from being read during transmission because they are encrypted. For more information, see basic security implementation policies for Web applications.
Determine whether the browser accepts cookies
Users can set their browsers to reject cookies. No error is thrown when the Cookie cannot be written. Similarly, the browser does not send any information about its current Cookie settings to the server.
Note:
The Cookie attribute does not indicate whether the Cookie is enabled. It only indicates whether the current browser originally supports cookies.
One way to determine whether a Cookie is accepted is to write a Cookie and then try to read it. If the Cookie you wrote cannot be read, you can assume that the browser does not accept the Cookie.
The following code example shows how to test whether the browser accepts cookies. This example consists of two pages. Write the Cookie on the first page and redirect the browser to the second page. The second page tries to read the Cookie. Then, redirect the browser back to the first page and add the query string variable with test results to the URL.
The code for the first page is as follows:
Copy codeThe Code is as follows: protected void Page_Load (object sender, EventArgs e)
{
If (! Page. IsPostBack)
{
If (Request. QueryString ["AcceptsCookies"] = null)
{
Response. Cookies ["TestCookie"]. Value = "OK ";
Response. Cookies ["TestCookie"]. Expires =
DateTime. Now. AddMinutes (1 );
Response. Redirect ("TestForCookies. aspx? Redirect = "+
Server. UrlEncode (Request. Url. ToString ()));
}
Else
{
Label1.Text = "Accept cookies =" +
Server. UrlEncode (
Request. QueryString ["AcceptsCookies"]);
}
}
}
This page is first tested to determine whether it is sending back. If not, search for the query string variable name AcceptsCookies that contain the test results. If the query string variable does not exist, the test is not completed. Therefore, the code will write a Cookie named TestCookie. After the Cookie is written, this example calls Redirect to switch to the TestForCookies. aspx test page. The URL appended to the test page is a query string variable named redirect that contains the URL of the current page. This will redirect you back to this page after the test is executed.
The test page can be fully composed of code, and does not need to contain controls. The following code example illustrates the test page.
Copy codeThe Code is as follows: protected void Page_Load (object sender, EventArgs e)
{
String redirect = Request. QueryString ["redirect"];
String acceptsCookies;
If (Request. Cookies ["TestCookie"] = null)
AcceptsCookies = "no ";
Else
{
AcceptsCookies = "yes ";
// Delete test cookie.
Response. Cookies ["TestCookie"]. Expires =
DateTime. Now. AddDays (-1 );
}
Response. Redirect (redirect + "? AcceptsCookies = "+ acceptsCookies,
True );
}
After reading the redirection query string variable, the Code tries to read the Cookie. For management purposes, if the Cookie exists, it will be deleted immediately. After the test is complete, the Code uses redirect to query the string variable passed to its URL to construct a new URL. The new URL also contains a query string variable containing the test results. The last step is to use the new URL to redirect the browser to the initial Page.
An improvement in this example is that you can save the Cookie test results to a permanent storage area (such as a database), so that you do not have to repeat the test each time you view the initial Page. (By default, cookies are required to store test results in the session state .)
Cookie and session Status
When you navigate to your site, the server creates a unique session for the user, and the session continues until the user's access ends. ASP. NET maintains session status information for each session. Applications can store user-specific information in session status information. For more information, see session status overview topic.
ASP. NET must trace the session ID of each user so that users can be mapped to session status information on the server. By default, ASP. NET uses non-permanent cookies to store session statuses. However, if the Cookie is disabled in the browser, the session status information cannot be stored in the Cookie.
ASP. NET provides a Cookie-free session as an alternative. You can configure the application to store the session ID in the URL on the page instead of the Cookie. If the application depends on the session status, you can configure it to use a non-Cookie Session. However, in rare cases, if a user shares a URL with others (the user may send the URL to a colleague, and the user's session is still active ), the two users may eventually share the same session, and the results will be unpredictable. For more information about configuring applications to use cookieless sessions, see ASP. NET status management overview.