Hello Friends,
Below is the information about cookies in ASP.NET and its conceptual view..
Basics of Cookies in ASP.NET
Visual Studio .NET 2003
Mike Pope
Visual Basic User Education
Microsoft Corporation
Visual Basic User Education
Microsoft Corporation
January 2003
Summary: Explains how to read and write HTTP cookies in an ASP.NET
Web application using Visual Basic. (18 printed pages)
Applies to
- ASP.NET
- Microsoft® Visual Studio® .NET
- Web Forms
Level: beginning Web programmer
Contents
Introduction
What Are Cookies?
Cookie Limitations
Writing Cookies
Multi-Valued Cookies (Subkeys)
Controlling Cookie Scope
Reading Cookies
Modifying and Deleting Cookies
Cookies and Security
Checking Whether a Browser Accepts Cookies
Cookies and Session State
What Are Cookies?
Cookie Limitations
Writing Cookies
Multi-Valued Cookies (Subkeys)
Controlling Cookie Scope
Reading Cookies
Modifying and Deleting Cookies
Cookies and Security
Checking Whether a Browser Accepts Cookies
Cookies and Session State
Cookies provide a useful means in
Web applications to store user-specific information. For example, when a user
visits your site, you can use cookies to store user preferences or other
information. When the user visits your Web site another time, the application
can retrieve the information it stored earlier.
This article provides an overview of
working with cookies in ASP.NET applications. I will show you the mechanics of
working with cookies in ASP.NET, such as writing them and then reading them
again later. Along the way, I will explain various features and (occasional)
oddities of cookies and the support in ASP.NET for them.
A cookie is a small bit of text that
accompanies requests and pages as they go between the Web server and browser.
The cookie contains information the Web application can read whenever the user
visits the site.
Imagine that when users request a page
from your site, www.contoso.com, your application sends not just a page, but a
cookie containing the date and time. When the user's browser gets the page, the
browser also gets the cookie, which it stores in a folder on the user's hard
disk.
Later, the user requests a page from
your site again. When the user enters the URL www.contoso.com, the browser
looks on the local hard disk for a cookie associated with the URL. If the
cookie exists, the browser sends the cookie to your site along with the page request.
Your application can then determine the date and time that the user last
visited the site. You might use the information to display a message to the
user, check an expiration date, or perform any other useful function.
Cookies are associated with a Web
site, not with a specific page, so the browser and server will exchange the
www.contoso.com cookie information no matter what page the user requests from
your site. As the user visits different sites, each site might send a cookie to
the user's browser as well; the browser stores all the cookies separately.
That's the basics of how cookies
work. But what are they good for? In essence, cookies help Web sites store
information about visitors. More generally, cookies are one way of maintaining
continuity in a Web application (formally, performing state management).
Except for the brief time when they are actually exchanging information, the
browser and Web server are disconnected. Each request you make to a Web server
is treated independently of any other request. Many times, however, it's useful
for the Web server to recognize you when you request a page. For example, the
Web server on a shopping site' keeps track of individual shoppers so the site
can manage shopping carts and other user-specific information. A cookie
therefore acts as a kind of calling card, presenting pertinent identification
that helps an application know how to proceed.
Cookies are used for all sorts of
purposes, all relating to helping the Web site remember you. For example, a
site conducting a poll might use a cookie simply as a Boolean value to indicate
whether your browser has already participated in voting so that you don't vote
twice. A site that asks you to log on might use a cookie to tell itself that
you've already logged on so that you don't have to keep entering your
credentials.
If you'd like more background
information about cookies, I recommend an article called "How Internet
Cookies Work" on the Verizon Web site at
http://www22.verizon.com/about/community/learningcenter/articles/displayarticle1/0,4065,1022z1,00.html.
The author goes into detail about what cookies are and how they are exchanged
between browser and server. He also includes a good summary of what the privacy
concerns are about cookies.
Incidentally, have you ever wondered
why they are called "cookies"? The Jargon File (aka The New
Hacker's Dictionary), version 4.2.2, has a good definition and a plausible
explanation of the term's etymology. You can find the entry at http://www.catb.org/~esr/jargon/.
From here on out, I will assume that
you know what cookies are and have a sense of why you might want to use them in
your ASP.NET applications.
Before we start on the mechanics of
working with cookies, I will mention a couple of limitations of working with
cookies. Most browsers support cookies of up to 4096 bytes. That is plenty of
space for storing a few values on the user's computers, but you would not want
to try to store a dataset or some other potentially large piece of data in a
cookie. More practically, you probably do not want to store a big collection of
user information in a cookie. Instead, you would want to store a user number or
other identifier. Then, when the user visits your site again, you would use the
user ID to look up user details in a database. (But see Cookies and Security for some caveats about
storing user information.)
Browsers also impose limitations on
how many cookies your site can store on the user's computer. Most browsers
allow only 20 cookies per site; if you try to store more, the oldest cookies
are discarded. Some browsers also put an absolute limit, usually 300, on the
number of cookies they will accept from all sites combined.
A cookie limitation that you are
likelier to run into is that users can set their browser to refuse cookies. You
cannot do much to get around this problem except to avoid cookies altogether
and use a different mechanism to store user-specific information. A common
method for storing user information is Session state, but Session state depends
on cookies, as I explain later in Cookies and Session State.
Note For
more information on state management and options for saving information in a
Web application, see Introduction to Web Forms State Management and State Management Recommendations.
The more general lesson is probably
that although cookies can be very useful in your application, the application
should not depend on being able to store cookies. Use cookies for nice-to-have
features; do not use them to support critical features. If your application
must rely on cookies, you can test to see whether the browser will accept
cookies. I outline a method for doing so in the section Checking Whether a Browser Accepts Cookies later
in this paper.
You write a cookie using the page's Response property, which exposes an object that
allows you to add to the information being rendered to the browser by the page.
The Response object supports a collection named Cookies, to which you add the cookies you want to
write to the browser.
Note The
Response object and the Request object, which I will discuss
shortly, are properties of the page that contain, respectively, instances of
the HttpResponse and HttpRequest classes. To find information in the
documentation about Response and Request, look under HttpResponse
and HttpRequest.
When you create a cookie, you
specify several values. To start with, you specify the name of the cookie and
the value to store in it. You can create multiple cookies, and each cookie must
have a unique name so you can identify it later when you want to read it.
(Cookies are stored by name, so if you create two cookies with the same name,
one overwrites the other.)
You might also want to specify the
cookie's expiration date and time. Cookies are normally written to the user's
disk, where they could potentially hang around forever. You can therefore
specify a date and time on which the cookie expires. When the user visits your
site again, the browser first examines the collection of cookies for your site.
If a cookie has expired, the browser does not send that particular cookie to
the server with the page request; instead, the expired cookie is deleted. (Your
site might have written multiple cookies to the user's computer; each cookie
can have a separate expiration date and time.) Notice that the browser is
responsible for managing cookies on the hard disk, a fact that affects what you
can do with cookies in your application, as I will explain shortly.
How long should the expiration
period be for a cookie? It depends on what you're using the cookie for, or to
put it another way, it depends on how long your application considers the
cookie value to be valid. If you're using cookies to count visitors to your
site, you might decide to set expiration to a year from now on the theory that
if someone hasn't visited your site in a year, you can consider that user a new
visitor. In contrast, if you use cookies to store user preferences, you might
set the expiration to effectively never expire (expiration of 50 years, say),
since a user might find it annoying to have to reset preferences periodically.
You might sometimes write a cookie that expires in seconds or minutes. Later in
the paper in the section Checking Whether a Browser Accepts Cookies I have
an example that creates a cookie whose practical lifetime is measured in
seconds.
Note Don't
forget that users can clear the cookies on their computer any time. Even if you
store cookies with long expiration times, a user might decide to delete all
cookies, wiping out any settings you might have stored in cookies.
If you do not set the cookie's
expiration, the cookie is created but it is not stored on the user's hard disk.
Instead, the cookie is maintained as part of the user's session information.
When the user closes the browser or if the session times out, the cookie is
discarded. A non-persistent cookie like this is handy for information that
needs to be stored for only a short time or that for security reasons should not
be written to disk on the client computer. For example, non-persistent cookies
are useful if the user is working on a public computer, where you do not want
to write the cookie to disk.
You can add cookies to the Response.Cookies
collection in a couple of ways. The following example shows two methods to
accomplish the task:
Response.Cookies("userName").Value = "mike"
Response.Cookies("userName").Expires =
DateTime.Now.AddDays(1)
Dim aCookie As New HttpCookie("lastVisit")
aCookie.Value = DateTime.Now.ToString
aCookie.Expires = DateTime.Now.AddDays(1)
Response.Cookies.Add(aCookie)
The example adds two cookies to the Cookies
collection, one called "userName" and the other called
"lastVisit." For the first cookie, I set values of the Response.Cookies
collection directly. You can add values to the collection this way because Response.Cookies
derives from a specialized collection of type NameObjectCollectionBase.
For the second cookie, I create an
instance of the cookie object (type HttpCookie), setting its properties, and then
adding it to the Response.Cookies collection via the Add method.
When you instantiate an HttpCookie object, you must pass the cookie name
as part of the constructor.
Both examples accomplish the same
task, namely writing a cookie to the browser. The method you use depends
largely on personal preference. You might find that the second method can make
it slightly easier to set cookie properties, but as you can see, the
differences are not dramatic.
In both methods, the expiration
value must be of type DateTime. However, the "lastVisited"
value is also a date-time value. In that case, however, I had to convert the
date-time value to a string. Any value that you store in a cookie is ultimately
stored as a string.
Peeking
at Your Cookies
You might find it useful to see the
effect of creating cookies. It is easy to look at the cookies — they are text
files, after all — as long as you can find them. Different browsers store
cookies in different ways. I'll describe how Internet Explorer stores cookies;
if you use a different browser, check the browser's Help to learn about cookie
handling.
A handy way to view cookies is to
have Internet Explorer find them for you. In Internet Explorer, from the Tools
menu choose Internet Options. In the General tab, click Settings, and then
click View Files. Internet Explorer opens a window that displays all its
temporary files, including cookies. Find the files whose name begins with
"Cookie:" in the window or look for text files. Double-click a cookie
to open it in your default text file.
Alternatively, you can explore
cookies by locating their text files on your hard disk. Internet Explorer
stores the cookies for a site in a file whose name is in the format <user>@<domain>.txt,
where <user> is your account name. For example, if your name is
mikepope and you visit the site www.contoso.com, the cookies for that site will
be in a file called mikepope@www.contoso.txt. (The name might include a sequential number, such as mikepope@www.contoso[1].txt.)
The cookie text files are
user-specific, so they are isolated by account. In Windows XP, for example, you
will find the cookie files in a directory with a name such as the following:
c:\Documents and Settings\<user>\Cookies
To find the cookie you are creating,
you might find it helpful to sort the directory by Date Modified and look for
the most recent file.
You can open the cookie with a text
editor. If the file contains multiple cookies, they are separated with an
asterisk (*). The first line of each cookie is its name, and the second has the
values. The remaining lines have cookie housekeeping information such as the
expiration date and time. There is also a simple checksum in the cookie; if you
change the length of the cookie name or value, the browser will detect the
tampering and will discard the cookie.
The previous example uses one cookie
for each value you want to store. (User name, last visit.) You can also store
multiple name-value pairs in a single cookie. The name-value pairs are referred
to as "keys" or "subkeys," depending on what you are
reading. (Subkeys are laid out much like a query string in a URL, should you
happen to be familiar with that structure.) As an example, instead of creating
two separate cookies named "userName" and "lastVisit," you
could create a single cookie named "userInfo" that has the subkeys
"userName" and "lastVisit."
There are a couple of reasons to use
subkeys instead of separate cookies. Obviously, it is tidy to put related or
similar information into a single cookie. In addition, because all the
information is in a single cookie, cookie attributes such as expiration apply
to all the information. (Conversely, of course, if you want to assign different
expiration dates to different types of information, you should store the
information in separate cookies.)
A cookie with subkeys also helps you
keep cookie size down. As noted earlier under Cookie Limitations, cookies are limited to 4096
bytes and you can't store more than 20 cookies per site. By using a single
cookie with subkeys, you use up fewer of those 20 cookies your site is
allotted. In addition, a single cookie takes up about 50 characters for
overhead (expiration information, and so on), plus the length of the value that
you store in it, all of which counts toward the 4K limit. If you store five
subkeys instead of five separate cookies, you save the overhead of the separate
cookies and can save around 200 bytes.
To create a cookie with subkeys, you
can use a variation of the syntax for writing a single cookie. The following
example shows two ways to write the same cookie, each with two subkeys:
Response.Cookies("userInfo")("userName") =
"mike"
Response.Cookies("userInfo")("lastVisit") =
DateTime.Now.ToString
Response.Cookies("userInfo").Expires =
DateTime.Now.AddDays(1)
Dim aCookie As New HttpCookie("userInfo")
aCookie.Values("userName") = "mike"
aCookie.Values("lastVisit") = DateTime.Now.ToString
aCookie.Expires = DateTime.Now.AddDays(1)
Response.Cookies.Add(aCookie)
By default, all cookies for a site
are stored together on the client and all cookies are sent to the server with
any request to that site — in other words, every page in a site gets all the
cookies for that site. At times you might want cookie behavior to be a little
more specific. You can set the scope of cookies in two ways:
- Limit the scope of cookies to a folder on the server,
which in practical terms allows you to limit cookies to an application on
the site.
- Set scope to a domain, which allows you to specify
which subdomains in a domain can access a cookie.
Limiting
Cookies to a Folder or Application
To limit cookies to a folder on the
server, set the cookie's Path property, as here:
Dim appCookie As New HttpCookie("AppCookie")
appCookie.Value = "written " & Now.ToString
appCookie.Expires = Now.AddDays(1)
appCookie.Path = "/Application1"
Response.Cookies.Add(appCookie)
Naturally, you can also write
cookies out by setting Response.Cookies directly, as I explained
earlier.
The path can either be a physical
path under the site root or a virtual root. The effect will be that the cookie
is available only to pages in the Application1 folder or virtual root. For
example, if your site is called www.contoso.com, the cookie created in the
previous example will be available to pages with the path
http://www.contoso.com/Application1/ and to any pages beneath that folder.
However, the cookie will not be available to pages in other applications such
as http://www.contoso.com/Application2/ or just http://www.contoso.com/.
Tip Some
testing with Internet Explorer and the Mozilla browser suggests that the path
is case sensitive. Ordinarily, URLs on Windows servers are not case sensitive,
but this appears to be an exception. You can't control how users type URLs into
their browsers, but if your application depends on cookies tied to a specific
path, be sure that the URLs in any hyperlinks you create match the case of the Path
property value.
Scoping
Cookies to a Domain
By default, cookies are associated
with a specific domain. For example, if your site is www.contoso.com, the
cookies you write are sent to the server when users request any page from that
site. (Except for cookies with a specific path value, as I explained in the
section immediately preceding.) If your site has subdomains — for example,
contoso.com, sales.contoso.com, and support.contoso.com — then you can
associate cookies with a specific subdomain. To do so, set the cookie's Domain
property, like this:
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 will be available only to pages in the specified subdomain.
You can also use the Domain
property to create a cookie that can be shared among multiple subdomains. For
example, set the domain as follows:
Response.Cookies("domain").Value = DateTime.Now.ToString
Response.Cookies("domain").Expires =
DateTime.Now.AddDays(1)
Response.Cookies("domain").Domain =
"contoso.com"
The cookie will then be available to
the primary domain as well as to sales.contoso.com and support.contoso.com.
When a browser makes a request to
the server, it sends the cookies for that server along with the request. In
your ASP.NET applications, you can read the cookies using the Request
object. The structure of the Request object is essentially the same as
that of the Response object, so you can read cookies out of the Request
object much the same way you wrote cookies into the Response object. The
following examples show two ways to get the value of a cookie named
"username" and display its value in a Label control:
If Not Request.Cookies("userName") Is Nothing Then
Label1.Text =
Server.HtmlEncode(Request.Cookies("userName").Value)
End If
If Not Request.Cookies("userName") Is Nothing Then
Dim aCookie As HttpCookie
= Request.Cookies("userName")
Label1.Text =
Server.HtmlEncode(aCookie.Value)
End If
Before trying to get the value of a
cookie, you should make sure that the cookie exists. Otherwise, you will get a System.NullReferenceException exception. Notice
also that I call the HttpServerUtility.HtmlEncode method to encode the
contents of a cookie before I display it in the page. I'm doing that here
because I'm displaying the contents of the cookie (which you ordinarily
probably do not do), and I want to be certain that a malicious user hasn't
snuck executable script into the cookie. For more about cookie security, see Cookies and Security.
Note Because
different browsers store cookies differently, different browsers on the same
computer won't necessarily be able to read each other's cookies. For example,
if you use Internet Explorer to test a page one time, but then later use a
different browser to test again, the second browser won't find the cookies
saved by Internet Explorer. Of course, most people typically use the same
browser for all their Web interaction, so this isn't a problem under most
circumstances. However, it might come up if you are testing your application
for browser compatibility, for instance.
Reading the value of a subkey in a
cookie is likewise similar to setting it. Here is one way to get the value of a
subkey:
If Not Request.Cookies("userInfo") Is Nothing Then
Label1.Text = _
Server.HtmlEncode(Request.Cookies("userInfo")("userName"))
Label2.text = _
Server.HtmlEncode(Request.Cookies("userInfo")("lastVisit"))
End If
In the previous example, I am
getting the value of the subkey "lastVisit," which I set earlier to
the string representation of a DateTime value. Remember that cookies
store values as strings, so if you want to use the lastVisit value as a date,
you have to convert it:
Dim dt As DateTime
dt =
CDate(Request.Cookies("userInfo")("lastVisit"))
The subkeys in a cookie are typed as
a collection of type NameValueCollection. Therefore, another way to
get an individual subkey is to get the subkeys collection and then extract the
subkey value by name, as shown here:
If Not Request.Cookies("userInfo") Is Nothing Then
Dim
UserInfoCookieCollection As _
System.Collections.Specialized.NameValueCollection
UserInfoCookieCollection
= Request.Cookies("userInfo").Values
Label1.Text =
Server.HtmlEncode(UserInfoCookieCollection("userName"))
Label2.Text =
Server.HtmlEncode(UserInfoCookieCollection("lastVisit"))
End If
As with setting the cookie, the
method you use to read a cookie is up to you.
What's
the Expiration?
You can read the name and value of a
cookie, but there is not much else to learn about a cookie. You can get the Domain
and Path properties, but those properties are of limited use. For
example, you can read the Domain property, but of course if your page is
not in the same domain as the cookie, you will not have received the cookie in
the first place.
What you cannot read is the cookie's
expiration date and time. It turns out that when the browser sends cookie
information to the server, the browser does not include the expiration
information. You can read the Expires property, but it always returns a
date-time value of zero.
Earlier under Writing Cookies I mentioned that the browser is
responsible for managing cookies; the Expires property is an example of
this. The primary purpose of the Expires property is to help the browser
perform housekeeping on its store of cookies. From the server's perspective,
the cookie either exists or it does not; the expiration is not a useful piece
of information on the server side. Therefore, the browser does not provide this
information when it sends the cookie. If you are concerned about the expiration
date of a cookie, you must reset it, as I will explain shortly under Modifying and Deleting Cookies.
To be clear, you can read the Expires
property of a cookie that you have set in the Response object, before
the cookie has been sent to the browser. However, you cannot get the expiration
back in the Request object.
Reading
Cookie Collections
The previous examples assume that
you want to read a specific cookie whose name you know. You might occasionally
need to read through all the cookies available to the page. To read the names
and values of all the cookies available to the page, you can loop through the Request.Cookies
collection using code such as the following:
Dim i As Integer
Dim output As String = ""
Dim aCookie As HttpCookie
For i = 0 to Request.Cookies.Count - 1
aCookie =
Request.Cookies(i)
output &=
"Cookie name = " & Server.HtmlEncode(aCookie.Name) &
"<br>"
output &=
"Cookie value = " & Server.HtmlEncode(aCookie.Value) & _
&
"<br><br>"
Next
Label1.Text = output
Note When
you run this code, you will probably see a cookie named
"ASP.NET_SessionId." That is a cookie that ASP.NET uses to store a
unique identifier for your session. The session cookie is not persisted on your
hard disk. For more about session cookies, see Cookies and Session State later in this article.
A limitation of the preceding
example is that if the cookie has subkeys, the display shows the subkeys as a
single name/value string. The cookie property HasKeys tells you whether the cookie has subkeys.
If so, you can drill down into the subkey collection to get individual subkey
names and values.
As I noted earlier, you can get
information about subkeys out of the cookie property Values, which is a collection of type NameValueCollection.
You can read subkey values from the Values collection directly by index
value. The corresponding subkey names are available in the AllKeys member of the Values collection,
which returns a collection of strings.
The following example shows a
modification of the previous example. It uses the HasKeys property to
test for subkeys, and if subkeys are detected, the example gets subkeys from
the Values collection:
Dim i As Integer
Dim j As Integer
Dim output As String = ""
Dim aCookie As HttpCookie
Dim subkeyName As String
Dim subkeyValue As String
For i = 0 To Request.Cookies.Count - 1
aCookie =
Request.Cookies(i)
output &= "Name
= " & aCookie.Name & "<br>"
If aCookie.HasKeys Then
For j = 0 To
aCookie.Values.Count - 1
subkeyName =
Server.HtmlEncode(aCookie.Values.AllKeys(j))
subkeyValue =
Server.HtmlEncode(aCookie.Values(j))
output &=
"Subkey name = " & subkeyName & "<br>"
output &=
"Subkey value = " & subkeyValue &
"<br><br>"
Next
Else
output &=
"Value = " & Server.HtmlEncode(aCookie.Value) & "<br><br>"
End If
Next
Label1.Text = output
Alternatively, you can extract the
subkeys as a NameValueCollection object, as shown here:
If aCookie.HasKeys Then
Dim CookieValues As _
System.Collections.Specialized.NameValueCollection = aCookie.Values
Dim CookieValueNames() As
String = CookieValues.AllKeys
For j = 0 To
CookieValues.Count – 1
subkeyName =
Server.HtmlEncode(CookieValueNames(j))
subkeyValue =
Server.HtmlEncode(CookieValues(j))
output &=
"Subkey name = " & subkeyName
& "<br>"
output &=
"Subkey value = " & subkeyValue &
"<br><br>"
Next
Else
output &= "Value
= " & aCookie.Value & "<br><br>"
End If
Note Remember
that I'm calling the Server.HtmlEncode method only because I'm
displaying the values of cookies in the page. If you are merely testing the
value of a cookie, you don't need to encode the value before using it.
At times you might want to modify a
cookie, perhaps to change its value or to extend its expiration. (Remember that
you cannot read a cookie's expiration date because the browser does not pass
the expiration information to the server.)
You do not really directly change a
cookie, of course. Although you can get a cookie from the Request.Cookies
collection and manipulate it, the cookie itself still lives someplace on the
user's hard disk. So modifying a cookie really consists of creating a new
cookie with new values and then sending the cookie to the browser to overwrite
the old version on the client.
The following example shows how you
might change the value of a cookie that stores a count of the user's visits to
the site:
Dim counter As Integer
If Request.Cookies("counter") Is Nothing Then
counter = 0
Else
counter =
CInt(Request.Cookies("counter").Value)
End If
counter += 1
Response.Cookies("counter").Value = counter.ToString
Response.Cookies("counter").Expires =
DateTime.Now.AddDays(1)
Or alternatively:
Dim ctrCookie As HttpCookie
Dim counter As Integer
If Request.Cookies("counter") Is Nothing Then
ctrCookie = New
HttpCookie("counter")
Else
ctrCookie =
Request.Cookies("counter")
End If
counter = CInt(ctrCookie.Value) + 1
ctrCookie.Value = counter.ToString
ctrCookie.Expires = DateTime.Now.AddDays(1)
Response.Cookies.Add(ctrCookie)
Deleting
Cookies
Deleting a cookie — physically
removing it from the user's hard disk — is a variation on modifying it. You
cannot directly remove a cookie because the cookie is on the user's computer.
However, you can get the browser to delete the cookie for you. The technique is
to modify the cookie as described above (that is, create a new cookie with the
same name) but to set the cookie's expiration to a date earlier than today.
When the browser checks the cookie's expiration, the browser will discard the
now-outdated cookie.
Deleting any one cookie is therefore
the same technique as creating that cookie, except that you use a date earlier
than today. The following example is slightly more interesting than deleting a
single cookie — it shows one way to delete all the cookies for the current
domain:
Dim i As Integer
Dim cookieName As String
Dim limit As Integer = Request.Cookies.Count - 1
For i = 0 To limit
aCookie =
Request.Cookies(i)
aCookie.Expires =
DateTime.Now.AddDays(-1)
Response.Cookies.Add(aCookie)
Next
Modifying
or Deleting Subkeys
Modifying individual subkeys is the
same as creating it in the first place:
Response.Cookies("userInfo")("lastVisit") =
DateTime.Now.ToString
Response.Cookies("userInfo").Expires =
DateTime.Now.AddDays(1)
A more complicated problem is how to
delete an individual subkey. You cannot simply reset the expiration date for
the cookie, because that would remove the entire cookie instead of a single
subkey. The solution instead is to manipulate the cookie's Values
collection, which holds the subkeys. First recreate the cookie by getting it
from the Request.Cookies object. You can then call the Remove
method of the Values collection, passing to the Remove method the
name of the subkey to delete. Then, as usual, you add the modified cookie to
the Response.Cookies collection so it will be sent in its modified form
back to the browser.
The following code shows how to
delete a subkey. In the sample, the name of the subkey to remove is specified
in a variable.
Dim subkeyName As String
subkeyName = "userName"
Dim aCookie As HttpCookie = Request.Cookies("userInfo")
aCookie.Values.Remove(subkeyName)
aCookie.Expires = DateTime.Now.AddDays(1)
Response.Cookies.Add(aCookie)
When you work with cookies, you must
be aware of the security vulnerabilities inherent in them. By security, I do
not mean privacy issues, as described in the article I referred you to under What Are Cookies? earlier; privacy is more of an
issue for users who are concerned about how the information in cookies can be
used. The security issues with cookies are similar to those of getting data
from the client. For starters, as far as your application is concerned, cookies
are another form of user input and are therefore subject to peeking and
spoofing. A user can as a minimum see the data that you store in a cookie,
since the cookie is available on the user's own computer. If the user is
inclined, he or she can also change the cookie before the browser sends it to
you.
The upshot is that you should never
store secrets in a cookie — no user names, no passwords, no credit card
numbers, and so on. Do not put anything in a cookie that should not be in the
hands of a user or of someone who might somehow steal the cookie.
Similarly, be suspicious of
information you get out of a cookie. Do not assume that the data is the same as
when you wrote it out; use the same safeguards in working with cookie values
that you would with data that a user has typed into a Web page. For example, I
applied HTML encoding to the contents of a cookie before I displayed the value
in a page. Doing so is a standard technique for sanitizing any information that
you display after getting it from a user, and working with cookies is no
different.
Another concern is that cookies are
sent between browser and server as plain text, and anyone who can intercept
your Web traffic can read the cookie. You can set a cookie property that causes
the cookie to be transmitted only if the connection uses the Secure Sockets
Layer (SSL, aka https://). SSL does not protect the cookie from being read or
manipulated while it is on the user's computer, but it does prevent the cookie
from being intercepted in transit. Again, I will not discuss SSL in this
article, but be aware that you can add transmission protection to cookies. For
more information about SSL, see the article Secure Sockets Layer: Protect Your E-Commerce Web Site with
SSL and Digital Certificates.
Given these security issues, how can
you use cookies safely? You can store non-critical data in cookies, such as a
user's preferences or some other information that, if compromised, has no
important effect on your application. If you do want to store sensitive
information such as a user ID in a cookie, you can encrypt the cookie. One
possibility is to use the ASP.NET Forms Authentication utilities to create an
authentication ticket that is stored as a cookie. I do not discuss encryption
in this article, but if you want to store sensitive data in a cookie, you
should explore the possibilities of hiding the information from prying eyes and
would-be spoofers.
You can find more information about
cookies and security vulnerabilities in the article Mitigating Cross-site Scripting With HTTP-only Cookies.
I mentioned earlier under Cookie Limitations the potential problem that a
user might have set their browser to refuse cookies. How do you know if you can
write and read cookies? No error is raised if a cookie can't be written (for
example, Response.Cookies doesn't throw an exception) , because the
server doesn't keep track of what happens after the page has been rendered. The
browser likewise does not send any information to the server about its current
cookie settings. (In case you're wondering, the HttpBrowserCapabilities.Cookies Property property
does not tell you whether cookies are enabled; it only tells you whether the
current browser inherently supports cookies.)
One way to determine whether cookies
are accepted is by trying to write a cookie and then trying to read it back
again. If you can't read the cookie you wrote, you assume that cookies are
turned off in the browser.
I've put together a simple example
to show how you might test whether cookies are accepted. The sample consists of
two pages. On the first page, I write out a cookie, and then I redirect the browser
to the second page. The second page tries to read the cookie. It in turn
redirects the browser back to the first page, adding to the URL a query string
variable with the results of the test.
The code for the first page looks
like this:
Sub Page_Load()
If Not Page.IsPostBack
Then
If
Request.QueryString("AcceptsCookies") Is Nothing Then
Response.Cookies("TestCookie").Value = "ok"
Response.Cookies("TestCookie").Expires = _
DateTime.Now.AddMinutes(1)
Response.Redirect("TestForCookies.aspx?redirect="
& _
Server.UrlEncode(Request.Url.ToString))
Else
labelAcceptsCookies.Text = "Accept cookies = " & _
Request.QueryString("AcceptsCookies")
End If
End If
End Sub
The page first tests to see if this
is a postback, and if not, the page looks for the query string variable (AcceptsCookies) that contains the test results. If there is no query
string variable, the test hasn't been completed, so the code writes out a
cookie called "TestCookie." After writing out the cookie, the sample
calls Response.Redirect to transfer to the test page
(TestForCookies.aspx). Appended to the URL of the test page is a query string
variable called redirect containing the URL of the current page; this will allow us
to redirect back to this page after performing the test.
The test page can consist entirely
of code; it doesn't need to contain controls. Here's the code I used:
Sub Page_Load()
Dim redirect As String =
Request.QueryString("redirect")
Dim acceptsCookies As
String
' Was the cookie
accepted?
If
Request.Cookies("TestCookie") Is Nothing Then
' No cookie, so it
must not have been accepted
acceptsCookies = 0
Else
acceptsCookies = 1
' Delete test cookie
Response.Cookies("TestCookie").Expires = _
DateTime.Now.AddDays(-1)
End If
Response.Redirect(redirect & "?AcceptsCookies=" &
acceptsCookies, _
True)
End Sub
After reading the redirect query string variable, the code tries to read the cookie.
For housekeeping purposes, if the cookie does in fact exist, it is immediately
deleted. When the test is finished, the code constructs a new URL from the URL
passed to it in the
redirect query string variable. The new URL
also includes a query string variable containing test results. The final step
is to use the new URL to redirect the browser to the original page.
The example is quite simple, but it
illustrates the basic principle of testing by trying the procedure and seeing
what happens. An obvious improvement would be to keep the cookie test results
in a persistent store so that the test doesn't have to be repeated each time
the user views the original page. However, this is a little trickier than it
looks. Cookies won't work, for obvious reasons. Another possibility would be to
store the test results in Session state, but by default, Session state relies
on cookies also, and if the browser won't accept cookies, Session state won't
work either. The solution to this last problem is to use "cookieless"
Session state. In the next section, I'll give you a very brief overview of how
Session state works with cookies.
When a user navigates to your site,
the server establishes a unique session for that user that lasts for the
duration of the user's visit. For each session, ASP.NET maintains a
server-based structure ("Session state") where applications can store
user-specific information. For more information, see the article Session State.
ASP.NET needs to be able to track a
session ID for each user so that it can map the user to Session state
information on the server. By default, ASP.NET uses a non-persistent cookie to
store the session state. If you used the example code under "Reading
Cookie Collections" in the section Reading Cookies, you probably saw among the
cookies a Session state cookie.
However, if a user has disabled
cookies on the browser, Session state cannot use a cookie to store the session
ID and Session state doesn't work. That's why I said earlier under Checking Whether a Browser Accepts Cookies that
after testing for cookies it might not be practical to store the results of the
test in Session state — no cookie, no Session state.
ASP.NET offers a workaround in the
form of "cookieless" sessions. You can configure your application to
store Session IDs not in a cookie, but in the URLs of pages in your site. By
keeping the Session ID in the URL, ASP.NET stores the ID in the browser, in a
manner of speaking, and can get it back when the user requests another page.
Cookieless sessions can get around
the problem of a browser that refuses cookies and allow you to work with
Session state. If your application relies on Session state, you might want to
configure it to use cookieless sessions. However, under some limited
circumstances, if the user shares the URL with someone else — perhaps to email
the URL to a colleague while the user's session is still active — then both
users might end up sharing the same session, with unpredictable results.
For more information on configuring
your application to use cookieless sessions, see the Knowledge Base article INFO: ASP.NET State Management Overview.
Enjoy the day with Lots of smile and Happiness.....
No comments:
Post a Comment