Flylib.com

Books Software

 
 
 

Creating a Shopping Cart


Creating a Shopping Cart

I also struggled with the issue of how to represent customer shopping carts. The obvious choice here is the ASP.NET Profile object. Using the Profile object offers several advantages.

Note

Browser cookies, Session state, and the Profile object are discussed in Chapter 22, "Maintaining Application State."


First, the Profile object is persistent. A customer can add items to a shopping cart during one visit and return many months later to complete a purchase.

Second, the Profile object is designed to handle both anonymous and authenticated users. Requiring a customer to register before adding items to a shopping cart does not create a good customer experience. An e-commerce application should make the process of adding an item to a shopping cart as easy as possible.

Finally, when you take advantage of the Profile object, you don't need to write any database logic to store shopping cart information. The Framework does all the hard work for you.

This all sounds good. Unfortunately, I encountered one issue with the Profile object that I could not overcome . I wanted to be able to perform database joins between the items in a shopping cart and other database tables such as the Products database table.

For example, when a customer views his shopping cart, the shopping cart should not display the price of a product when the customer added the item to their shopping cart. Instead, the shopping cart should display the current price of the product (imagine that a customer adds an item to the shopping cart while the item is on sale and returns many months later).

When you store items with the Profile object, all the items are stored as a blob. You can't perform database queries against the individual items contained in a Profile . In particular, you can perform database joins between items in a Profile and other database tables.

Therefore, I created a custom ShoppingCart component to represent customer shopping carts. The ShoppingCart component is in the App_Code folder.

The custom ShoppingCart component persists customer shopping carts. The component stores shopping carts in a database table named ShoppingCart s.

The custom ShoppingCart component handles both anonymous and authenticated users. It does it the same way that the Profile object does. Anonymous Identification is enabled in the web configuration file. When Anonymous Identification is enabled, a persistent cookie containing a unique identifier is added to each anonymous customer's browser. This unique identifier is used when an anonymous customer's shopping cart is stored and retrieved.

The Global.asax file includes a Profile_OnMigrateAnonymous() event handler. This event handler calls a method of the ShoppingCart class named AuthenticateCart() when an anonymous user logs in or registers. This method updates the ShoppingCarts database table by replacing the customer's anonymous identifier with the customer's authenticated username.

Finally, the custom ShoppingCart component caches customer shopping carts in Sessions state. A customer's shopping cart does not need to be retrieved from the database with each page request. Instead, the shopping cart is stored in the web server's memory while the customer browses the website. This is done to improve performance.



Protecting Credit Card Numbers

Storing credit card numbers in plain text in the database is an extremely bad idea. If a customer trusts you with a credit card number, you should do everything in your power to protect the information.

The best option is to never store credit card numbers at all. If you process a customer credit card number immediately after the customer submits it, then you can discard the credit card number when the transaction completes.

Note

If you want to modify the e-commerce application to process credit cards immediately, one easy way to do this is to take advantage of the PayPal SDK. To learn more about the PayPal SDK, visit the following website:

http://www.paypal.com/cgi-bin/webscr?cmd=xpt/cps/general/SoftwareDevKit-outside


The e-commerce application stores credit card numbers in the Orders database table. Credit card numbers are not stored in plain text. Instead, they are encrypted before being added to the database.

The e-commerce application uses a component named Secret to encrypt and decrypt credit card numbers. The Secret component is located in the App_Code folder.

Note

You should use a Secure Sockets Layer (SSL) connection between a browser and web server whenever a user submits sensitive information, such as a credit card number, in a form. SSL encrypts the data that is passed across the Internet. You can enable SSL when serving pages with Internet Information Server by installing an SSL certificate. You need to purchase an SSL certificate from a Certificate Authority such as Verisign (www.verisign.com) or Thawte (www.thawte.com).


The Secret component uses the RijndaelManaged class from the System.Security.Cryptography namespace to encrypt and decrypt strings. The Rijndael algorithm is also known as the Advanced Encryption Standard (AES). It is the United States government encryption standard.

To use the RijndaelManaged class to encrypt a string, you must supply an encryption key and an initialization vector (IV). The encryption key must be kept secret. The IV, on the other hand, does not need to be kept secret. You need both the encryption key and IV to decrypt an encrypted string.

The Secret component loads the encryption key from the machineKey section of the web configuration file. The component reads the value of the decryptionKey attribute. The component uses the same key that is used by the ASP.NET Membership framework. The IV is generated from the first bytes of the encryption key.

If you change the value of the decryptionKey attribute in the web configuration file, then you can't retrieve any of the credit card numbers stored in the database. Credit card numbers are retrieved as a string of question marks.

Warning

The sample application contains a machineKey section with a decryptionKey attribute in the web configuration file. You need to change the value of the decryptionKey attribute to a new value. You can generate a new decryptionKey by using the GenerateKeys.aspx page described in Chapter 21, "Using ASP.NET Membership."


Of course, all this encryption is meaningless if a hacker gets access to the Manage\Orders\Default.aspx page. This page displays order information, including the credit card number associated with an order. The page is password protected so that only members of the StoreAdmins role can access the page. However, if a hacker manages to bypass the ASP.NET Authentication framework, then all bets are off.