Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shopping cart persistence: $_SESSION or browser cookie?

People also ask

Should I use session or cookie?

Sessions use a cookie as a key of sorts, to associate with the data that is stored on the server side. It is preferred to use sessions because the actual values are hidden from the client, and you control when the data expires and becomes invalid.

Does shopping cart use cookies?

Cookies in ecommerceEcommerce sites use a combination of session cookies and persistent cookies to create a seamless shopping cart experience. As the user adds items to her cart, session cookies keep track of the items.

Do sessions last longer than cookies?

Cookies are client-side files that are stored on a local computer and contain user information. Sessions are server-side files that store user information. Cookies expire after the user specified lifetime. The session ends when the user closes the browser or logs out of the program.

Why is session tracking better than cookies?

Sessions are more secured compared to cookies, as they save data in encrypted form. Cookies are not secure, as data is stored in a text file, and if any unauthorized user gets access to our system, he can temper the data.


Neither

No large sites would dare store a user's cart in a session or cookie - that data is just to valuable.

What customers are buying, when they select items, how many they purchase, why they don't finish the checkout, etc.. are all very, very important to your business.

Use a database table to store this information and then link it to the user's session. That way you don't lose the information and you can go back and build statistics based on users carts or solve problems with your checkout process.

Log everything you can.

Database Schema

Below is a simplified example of how this might look at the database level.

user {
    id
    email
}

product {
    id
    name
    price
}

cart {
    id
    product_id
    user_id
    quantity
    timestamp    (when was it created?)
    expired      (is this cart still active?)
}

You might also want to split the cart table out into more tables so you can track revisions to the cart.

Sessions

Normal PHP Sessions consist of two parts

  1. The data (stored in a file on the server)
  2. A unique identifier given to the user agent (browser)

Therefore, it's not $_SESSION vs $_COOKIE - it's $_SESSION + $_COOKIE = "session". However, there are ways you can modify this by using a single encrypted cookie which contains the data (and therefore you don't need an identifier to find the data). Another common approach is to store the data in memcached or a database instead of the filesystem so that multiple servers can access it.

What @Travesty3 is saying is that you can have two cookies - one for the session, and another that is either a "keep me logged in" cookie (which exists longer than the session cookie), or a copy of the data inside separate cookie.


As pointed out by Xeoncross, it is very important to store any possible information for analysis. So one should not entirely rely on sessions and cookies.

A possible approach is-

Use sessions if not logged in

If the user is not logged in, you can store and retrieve the cart items and wishlist items from session using $_SESSION in PHP

Use database when logged in

If the user is logged in then you can consider one of the two options -

  • Store the cart item or wishlist item in database alone
  • Store the cart item or wishlist item in database as well as in session (This will save some of your database queries)

When user logs in

When the user logs in, get all the cart items and wishlist items from the session and store it in the database.

This will make the data persistent even if the user logs out or changes the machine but till the user has not logged in, there is no way to store the information permanently so it will not be persistent.

Getting required data

Whenever you are trying to access cart or wishlist do the following check -

  • If the user is not logged in then look into session
  • If the user is logged in, query database if you are storing in the database alone, otherwise you can just look into sessions if you are keeping session updated along with the database

I would store it in a SESSION. My wish list is rather long, and I am afraid that it will not fit in the 4K storage that a COOKIE may occupy. It forces you set the session time out to a longer period.

note: there are some countries (like the Netherlands, where I am) that have very strict policies about cookies, and you may be forced by legislation to use Sessions.


Some points to help:

Cookies:

  • info is persisted untill the cookie expires (what can be configured by you);
  • tend to slow down the communication between server and client, since it has to be exchanged between the two in every request/response;
  • its an insecure form of storing data and easy to sniff;
  • they also have a limit to store data.

Session:

  • all information is persisted in the server, thus not been exchanged with the client.
  • because it is not shared across the network, its a bit more secure;
  • all info is lost when the session ends;
  • If you are hosting in a shared host, you may have problems with session ending in the middle of a operation due to a push on the resources by any of the sites hosted on the same server.

I would personally go with sessions, since I'm assuming to be a small/meddium auddience page. If it grows, you would be better with a simple DB structure to store this data, with a maintenance plan to get ridge of unnecessary data (eg: clients that choose some products but don't do the checkout).


You might consider using both.

The drawback with $_SESSION is that the session is cleared when the browser is closed.

Use sessions, but attempt to populate the $_SESSION data from a cookie, if it's available.


I would use a session. If a user has cookies disabled then the session won't be able to start as the session ID is stored on the user's machine in a cookie.

There are some settings you may want to look at in order to attempt to keep the sessions for longer.

  • Prevent the session cookie from being deleted when the user closes their browser by running session_set_cookie_params() with the lifetime parameter set. This function needs to run before session_start()

  • You may also want to extend how often sessions are cleared from the server by modifying the session garbage collection settings session.gc_probability, session.gc_divisor, session.gc_maxlifetime either in php.ini or using ini_set()

  • If you have other websites running on the server and you modify the above garbage collection settings you will need them set in php.ini so they apply to all websites, or if you are using ini_set() then you might also look at saving these sessions to a different directory than other websites by modifying session_save_path(). Again this is run before session_start(). This will prevent the garbage collection of other websites clearing up your extended sessions for one particular site.

  • I would also recommend setting the following session settings in php.ini session.entropy_file = /dev/urandom, session.entropy_length = 256, session.hash_function = sha512. That should give you a cryptographically strong session ID with an extremely tiny chance of collisions.

  • And make sure you have an SSL cert on your site to prevent man in the middle attacks against your session ID.

Obviously a user could still decide to manually clear all their cookies which will take the session ID cookie with it but that's a risk I'd be prepared to take. If I was halfway through a shopping cart system and hadn't checked out, I wouldn't go and clear my cookies. I still think sessions are better than just using plain cookies.

The data is secure enough so long as you are the only website that has access to your sessions directory and your session ID is strong. And by extending the server's session storage time your data can persist on the server.

There are further measures you could employ to make your sessions even stronger. Regenerate your session ID every 20 minutes, copying the data over. Also record session IDs against IP addresses in a database and check to see if a particular IP address attempts to send more than X number of session IDs in a given time to prevent someone trying to brute force a session ID.

You could also store the data in a database linked by the session ID, instead of in a session file on the server. However this is still reliant on a session ID which is stored in a cookie and could disappear at any time. The only way to truly be sure that a user doesn't lose their cart is by having them login first and storing in a database.