• No results found

Using HTTP Cookies

In document Ajax Patterns And Best Practices pdf (Page 167-170)

The other way of creating a user identifier is to use an HTTP cookie, as illustrated in Figure 5-9. Frameworks such as ASP.NET have made it very comfortable to implement user identifiers that are cross-referenced with an HTTP cookie. The cross-referencing of the HTTP cookie with the authorization of a resource is not implemented by default in ASP.NET, but it is not difficult to implement.

Generating the Cookie

It is possible to generate an HTTP cookie3 without using any help from a library. Because of the prevalence of cookies, most server-side libraries have classes or functions to generate cookies based on a few parameters. Using the available server-side libraries is highly recommended.

Generating the cookie by using the server-side libraries is not difficult. When using ASP.NET, the following source code would be used:

HttpCookie mycookie = new HttpCookie("Sample", "myvalue"); mycookie.Path = "/ajax/chap05";

Page.Response.Cookies.Add(mycookie);

A cookie is instantiated (HttpCookie) and at a minimum the key (Sample) and value (myvalue) are specified. The combination key-value pair is sent between the client and server. The cookie property mycookie.Path specifies for which URL and its descendents the cookie is valid. Comparing

this to HTTP authentication, the cookie path is equal to the HTTP authentication realm. The newly created cookie is added to the response by using the method Page.Response.Cookies. Add. When a cookie is added, the HTTP response will generate a cookie using the Set-Cookie

HTTP header, as illustrated by the following HTTP server response:

HTTP/1.0 200 OK

Server: Mono-XSP Server/1.0.9.0 Unix X-Powered-By: Mono

Date: Sun, 28 Aug 2005 17:31:14 GMT Content-Type: text/html; charset=utf-8 Set-Cookie: Sample=myvalue; path=/ajax/chap05 Content-Length: 388

Keep-Alive: timeout=15, max=99 Connection: Keep-Alive

The cookie Sample has a value of myvalue and is valid for the path /ajax/chap05. Because there is no expires value, the cookie is valid only for the lifetime of the browser. If the browser is closed, the cookie is deleted, thus behaving like an HTTP authentication-based user identifier.

Understanding How the Client Manages the Cookie

When the client receives the cookie, the cookie will automatically be saved if the client is a browser or the XMLHttpRequest object of the browser. In fact, the JavaScript on the client side has to do absolutely nothing with the assigned cookie because everything occurs transpar- ently. For example, if a browser loads a page and a cookie is assigned for the entire domain, and then when the XMLHttpRequest object calls a page within the domain, the cookie will be sent.

One thing that is not recommended is the storing of sensitive information within the cookie. Storing passwords or any kind of personal information is not recommended. A cookie is a reference to information, not a repository for information. When a user has been authenti- cated by using other means, a cookie should be used only as a token to identify the user.

Identifying a User with a Cookie

When the server generates a cookie, it means nothing because a cookie is just a token. Going back to the shopping mall example, it is equivalent to giving each person a token that provides a reference to that person, and as that person wanders the mall, data is generated. To cross- reference the token, an authentication mechanism has to be applied. Two authentication mechanisms could be used. The first is to tie the cookie with HTTP authentication. The second is to create an HTML page that associates the cookie with a user.

Using HTTP authentication to associate a user with a cookie would involve protecting a file that requires an explicit authentication. When the user is authenticated by using HTTP authentication the protected file is responsible for associating the cookie and authentication information.

Implementing HTTP authentication in the context of a cookie is similar to the pure HTTP authentication example. The URL used to authenticate the user has a slightly modified imple- mentation. The same interfaces are used in the HTTP authentication example except that the

IUserIdentificationResolver<> implementation resolves the authorization and associates it with the cookie. Other than the slight modification of IUserIdentificationResolver<>, the exact same source code as was illustrated in the HTTP authentication can be used. The difference

is where the association of user identification to cookie occurs. For the example using ASP.NET, the protected URL would be authentication.aspx, and the implementation of authentication. aspx would be as follows:

<%@ Page Language="C#" %>

<%@ Import Namespace="Component.Authentication" %> <script runat="server">

public void Page_Init( Object source, EventArgs ev) { IUserIdentificationResolver< HttpRequest> resolver = new HttpAuthenticationToCookieResolver(

new UserIdentificationFactory());

IUserIdentification user = resolver.Resolve(Page.Request); if (!user.IsIdentified) {

Page.Response.StatusCode = 500;

Page.Response.StatusDescription = "No authorization information"; Page.Response.SuppressContent = false; Page.Response.End(); } else { Session["useridentifier"] = user; } } </script> <html> <head runat="server"> <title>Protected</title> </head> <body> Success! </body> </html>

In the ASP.NET page, the function Page_Init implements the initialization phase of the page loading. The init phase is called before the page is processed, and is ideal to test whether the user is authorized. In the implementation, the first two lines, which instantiate the

HttpAuthenticationToCookieResolver type and call the method Resolve, are identical to the user identification examples using HTTP authentication.

What is different from the HTTP authentication examples is that the instantiated

IUserIdentification instance is tested to see whether the user is identified. If the user is not identified (!user.IsIdentified), an HTTP 500 error is generated with the message that there is no authorization information. It might be tempting to return an HTTP 401 error to indicate an unauthorized access to the document, but that would be incorrect. It would be incorrect because authentication.aspx is not responsible for implementing HTTP authentication. That is the job of the administrator. If an HTTP 500 error has been generated, what has happened is that the administrator did not protect the URL.

If authorization information is associated with the request, the user variable will reference an authenticated user instance that could be assigned to the Session variable. In ASP.NET,

the Session variable is the session information associated with the cookie sent by ASP.NET. Then whenever any handler is called, the Session will contain a reference to the identified user.

The user does not have to be authenticated using HTTP authentication. An HTML form could be used instead. Using the HTML form, the developer is responsible for providing code that manages a user. Because of this added code, the HTTP authentication mechanism is preferred because it is the basis of the HTTP protocol.

In document Ajax Patterns And Best Practices pdf (Page 167-170)