An Introduction to Cookies
basix

An Introduction to Cookies

Tutorial Details
  • Difficulty: Beginner
  • Completion Time: 30 minutes

You might have heard about cookies, but what exactly are they and what can we actually do with them? In this tutorial, we will focus on the basics of cookies, and learn about their functionality in various web application and site environments. We will also learn how to use them within our PHP and JavaScript projects, while paying particular attention to security issues that might arise when using them. After reading this, you’ll have acquired the necessary skill set to implement cookies safely into your own web applications.


Step 1. Understanding Cookies

The first step on our journey is to discovered just what these cookies actually are! Even if you have already worked with them, you might still find this part quite useful – so stay with me!

Abstract

You can most easily think of cookies as text files, which are saved to your computer. On the request of a webserver, your browser creates such a file. After this happens, the webserver can read and write content from and to this file. Although this seems like a dangerous feature – after all, no one likes other people writing files to their computer, there are a few restrictions in place to make this process as safe as possible.

  • Web servers can only access cookies which are set to their own domain. This domain is set by the browser when a new cookie is requested by the web server, and can only be the domain or a subdomain of the web server (the web server can choose a subdomain if it wants to). This means that cookies which were set by, for example, google.com can’t be read by mozilla.com, and vice versa.
  • According to the HTTP protocol, cookies can’t be larger than 4096 Bytes (4KB) each.
  • There is a limit to the number of cookies per domain. The number differs per browser, however, the generally used limit is twenty cookies. This is to prevent a single domain from hogging the disk space of the client.
  • There is a limit to the total number of cookies on the client’s harddrive. This number also differs per browser, but is usually limited to around three hundred cookies. When this number is exceeded, an older cookie is deleted before a new one is created.

Cookies have an expiration date. This date is set so the browser can delete old cookies when they are no longer needed by the webserver. If the expiration date is empty, the cookie will be deleted when the connection with the server is closed. This occurs when the site’s window or tab is closed by the user, or when the user closes the entire browser. These cookies, sometimes called session cookies, are mostly used for storing temporary settings.

Technical

Let’s find out what these things look like on a technical level. Cookies are transfered via the HTTP protocol. This is the protocol used by browsers to retrieve and send files to the server. After a cookie has been requested, it is sent to the server every time a new item on the web page is fetched by the browser. Below, we can see a snippet of a server requesting a new cookie (this snippet is a part of a HTTP response).

Set-Cookie: Name=content data; expires=Fri, 31-Dec-2010 23:59:59 GMT; path=/; domain=.example.net

Now don’t get scared, it’s all very understandable!

  • Set-Cookie: is to let the browser know that the server would like to create a new cookie.
  • Name is the name of the cookie. Each cookie in a domain must have a different name, so the browser can keep all the cookies apart. After the name comes the =content data where ‘content data’ is the data which is to be contained in the cookie. This data can be a text string or a number, and, as said, can be up to 4KB in size.
  • expires= is the command for the expiration date. The expiration date is in the “Wdy, DD-Mon-YYYY HH:MM:SS GMT” format (Don’t ask me why it was defined to this rediculous format, because I don’t know either. No user ever sees the expiration date, so why waste memory, hard disc space, and bandwith on long dates?). Don’t worry about it though, because most programming languages have easy to use functions available to you. The browser automatically deletes cookies with an expiration date in the past.
  • The domain and path require some deeper explanation. The domain is the domain in which the cookie will be active. If the domain is ‘ads.google.com,’ the cookie will only be sent to the server of that domain, and if the domain is ‘google.com,’ the cookie will be sent to any server of any of the subdomains of Google, including google.com itself.
  • The path is the path of the domain to which the cookie is sent. This means that, if the path is set to ‘/images/,’ and the domain is set to ‘ads.google.com,’ the cookie will only be sent to the server if the browser requests a file from ‘ads.google.com/images/’. If the path is set to ‘/’, the cookie will be sent to the server regardless of the location of the requested file on the server.

In the next step, we’ll review how these properties can be used in programming languages.


Step 2. How to Create and Read Cookies

Cookies can be created in many ways, but, for the purposes of this tutorial, we will focus on PHP and JavaScript.

PHP

The most important thing to remember, when creating a cookie in PHP, is that you must set all cookies before you send any data to the browser. This means that you should always initialise new cookies before any output. This includes echo() or print() commands, and the <html> or <body> tags. Of course, there are some exceptions, but this is a general rule of thumb.

<?php
/***Creating a cookie***/
$name = 'clientname';
$value = 'Peter Griffin';
//time() gives current time in seconds, and we add 60 seconds * 30 = 30 minutes
//so this cookie expires in 30 minutes.
//You may notice that the expire date is in seconds, PHP translates this to
//the correct format internally!
$expireDate = time() + 60 * 30;
$path = '/example/';
$domain = 'test.envato.com';
$secure = false; //only transmit the cookie if a HTTPS connection is established
$httponly = true; //make cookie available only for the HTTP protocol (and not for JavaScript)
setcookie( $name, $value, $expireDate, $path, $domain, $secure, $httponly);

<html>
.... //all content etc goes here
?>

This should seem familiar by now, except for $secure and $httponly. The ‘secure’ is to force the cookie to only be sent if an HTTPS connection has been established, if set to true, and should normally be set to false. The ‘httponly’ makes the cookie only available through the HTTP protocol, meaning that client-side languages, like JavaScript and VBscript, can’t access the cookie. This helps to prevent nasty stuff, such as Cross Site Scripting, and should be set to true if you have no intentions of editing the cookies client-sided with a language like JavaScript. Also, to prevent misconceptions, “httponly” does not mean that cookies can’t be sent over HTTPS, because they still can, in fact. However, please do note that the above snippet can be made quite smaller (and should be):

<?php
setcookie( 'clientname', 'Peter Griffin', time()+60*30, '/example/', 'test.envato.com', false,true);
?>

Great! Now we can create cookies, but we have to be able to read them as well. Luckily for us, PHP makes this very easy once a cookie has already been created. In PHP, there’s an environment variable called $_COOKIE[], which can be used for extracting the value of the cookie. To use it, just insert the name of the cookie inside the brackets [] like so:

<?php
$cookieValue = $_COOKIE['name of the cookie'];
?>

This environtment variable can be used like any other. Just like $_GET[] and $_POST[], it can be treated directly as a normal variable (once you have checked if the cookie does indeed exist ofcourse) if you want to.

If you want to alter the expiration date, path, or domain, you have to overwrite an existing cookie with setcookie() using the same name as the original cookie. If you alter the expiration date to be in the past (time()-30*60 for instance), the cookie will be deleted.

JavaScript

Cookies can be read and written client-sided as well. Even though JavaScript doesn’t offer a nice solution to read and write cookies, it is possible and widely used. JavaScript uses the document.cookie object for cookie manipulation, as shown in the following snippet:

//get current date
var expiredate = new Date();
//increase date by 5 hours
expiredate.setHours( expiredate.getHours() + 5);
document.cookie = 'cookiename=cookievalue; expires='  + expiredate.toUTCString() + 'path=/example/; domain=test.envato.com'; 

As you might have noticed, this syntax is quite similar to the HTTP protocol notation. This has the advantage of being more in control, but also introduces some potential problems. Below is the <painful> snippet for reading a cookie.

var cookieName = 'testcookiename';
var textArray = document.cookie.split(';'); //put all the parts of the string in an array
for(var i = 0; i < textArray.length; i++){ // loop though all string pieces
var textPiece = textArray[i]; //contains 1 string piece
 //filter beginning spaces
while(textPiece(0)==' ') textPiece = textPiece.substring(1,textPiece.length);
//if the textpiece contains our cookies name
if (textPiece.indexOf(cookieName)== 0){ 
 //return whats after the cookies name
return textPiece.substring(cookieName.length,c.length);
}
}

I know, I know; this is a pain. Luckily for you guys, I’m posting some pre-written functions below (you might want to make your own functions for learning purposes though, and you should!).

function writeCookie(cookieName, cookieValue, expireHours, path, domain){
var date =  new Date();
date.setHours(date.getHours + expireHours);
document.cookie = cookieName + '=' + cookieValue + '; expires=' + date + '; path=' + path + '; domain=' + domain;
}

function readCookie(cookieName){
var textArray = document.cookie.split(';');
for(var i = 0; i < textArray.length; i++){
var textPiece = textArray[i]; 
while(textPiece(0)==' ') textPiece = textPiece.substring(1,textPiece.length);
if (textPiece.indexOf(cookieName)== 0) return textPiece.substring(cookieName.length,c.length);
}
}

Please do bear in mind that these snippets don’t contain any error checking.


Step 3. What to do with Cookies

Did you know? -
Cookies were invented by Netscape, which wanted to use them for creating a shopping cart for an online shop. Thanks to cookies people were able to keep items their cart, even after disconnecting from the shop.

Nowadays, we use cookies for almost every purpose you can think of. You can use them for saving user settings like name, language, location or screen size. This can improve the quality of the service you want to provide for a client, because you can optimize the service for a client and remember this optimization in the future. For instance, you could save the client’s preferred language to a cookie, and, afterward, show your site’s content in the preferred language every time the client visits your site.

Of course, there are plenty more fun things to do with cookies than this! In the next step, I’ll show you an example of a cool code snippet.


Step 4. Writing Cool Stuff

Finally! Now we can start writing some awesome code! Below is a bonus snippet, which uses cookies to create a relogin mechanism.

“Remember me” login snippet

Before we begin, this snippet contains some MySQL code. If you’re not familiar with MySQL, don’t panic. Even though this snippet is a bit difficult, it should be understandable with a bit of basic PHP and cookie knowledge.

To create a “remember me” implementation, we must have a few things. Firstly, we need a database table containing a username, password, and identification field. Secondly, we need a unique string or number to identify clients safely through cookies (this is the identification in the database table). In this snippet, we’ll use an SHA-1 digest, which is just a string, as an identifier. When used properly, this provides excellent security.

Most people just insert a username and password in the cookie, and send it to the server to automatically. This should be avoided at all times! Cookies are usually sent through a non-secure connection, so the content could easily be seen by any potential attackers.

<?php

//this assumes that the user has just logged in
/****Creating an identification string****/

$username; //normally the username would be known after login

//create a digest from two random values and the username
$digest = sha1(strval(rand(0,microtime(true)) + $username + strval(microtime(true)); 

//save to database (assuming connection is already made)
mysql_query('UPDATE users SET reloginDigest="'.$digest.'" WHERE username="'.$username.'"');  

//set the cookie
setcookie( 'reloginID', $digest, time()+60*60*24*7,'/', 'test.example.com', false, true);
//this assumes that the user is logged out and cookie is set
/****Verifying users through the cookie****/

$digest = $_COOKIE['reloginID'];
$digest = mysql_real_escape_string($digest); //filter any malicious content

//check database for digest
$result = mysql_query('SELECT username FROM users WHERE reloginDigest="'.$digest.'"');
//check if a digest was found
if(mysql_num_rows($result) == 1){
	$userdata  = mysql_fetch_object($result);
	$username = $userdata->username;

	//here you should set a new digest for the next relogin using the above code!

	echo 'You have successfully logged in, '.$username;

} else{
//digest didn't exist (or more of the same digests were found, but that's not going to happen)
echo "failed to login!";
}

?>

By using a digest like we did, the chances of getting two of the same digest is miniscule. A digest is a forty character string, which, in theory, should always provide a complete random ouput if the input is changed. In practice, you should add a time limit in the serverside code, so that the digest isn’t valid after X minutes. This prevents attackers from copying someone’s cookies and using them to login.


Step 5. Best Practices

We’ve almost reached the end of this tutorial. As a conclusion I would like to sum up some best practices:

  • Never insert sensitive data into a cookie. A client could be browsing on a public computer, so don’t leave any personal information behind.
  • Never trust data coming from cookies. Always filter strings and numbers! An attacker could write malicious data to the cookie in order to do something you don’t want your service to do.
  • Try to estimate how long the cookie should be valid, and set the expiration date accordingly. You don’t want to hog the client’s computer with old cookies which are set to expire in a hundred years.
  • Always set the secure and httponly to meet your application demands. If your application doesn’t edit the cookies with JavaScript, enable httponly. If you always have an HTTPS connection, enable secure. This improves the data’s integrity and confidentiality.

Conclusion

I hope you’ve learned a bit from today’s Nettuts+ tutorial. If you have any questions, feel free to leave a comment or say hi on Twitter.

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.jeba.in Jeba

    hmm.. yummy :-)

    • aiman

      thats what im looking for,i really eeeeeeeeeeennnnnnnnnnnjjjjjjjjjjjjjjjjjjoooooooooooooooyyyyyyyyyyyyy your tuts;

  • Mohamed Zahran

    That’s what i’m looking for, I really enjoy your tuts!

    Thank you

  • Chris

    Excellent tutorial! I already knew about cookies, but this made them crystal clear! Great examples and code snipets as well. Now I will be able to implement cookies more easily and securely.

  • Chris

    Hey nice tut but a few syntax errors in the snippets:

    In lines 15 & 20 of the “remember me” example you’ve mixed ” & ‘ in the values.
    In line 32 when echoeing out the string you’ve started with ” & close it with ‘
    Just thought i’d let you know.

    • Tom
      Author

      I saw it too, and i’ve sent a request for change. Thanks for noticing! :)

  • http://www.stephendurr.co.uk Steve Durr

    Perfect timing, thanks :)

  • tashi

    I got refreshed my knowledge about cookie with this tuts !!!
    Thank you Tom. Good work.

  • Zoran

    Really nice tutorial you have, thank you, though i have some questions considering “Never insert sensitive data into a cookie. A client could be browsing on a public computer, so don’t leave any personal information behind.” How is Facebook then storing cookies when you login? Cause i don’t have to re-login from facebook (and many other sites), even from different computers.

    • Tom
      Author

      By ‘sensitive data’ I mean usernames, real names, adresses, emails, personal details etc. The point I wanted to make is that cookies can be easily seen by others (which is especially true on public computers), and so it is best practice not to leave any details behind which might be private. You wouldn’t leave a note in a library with your name and adress on it, so why leave it in a cookie? ;)

  • Patrick

    Right. Cookies are good stuff. But…

    Sorry, are you crazy? You save a “rememberID” at the client and log in the user WITHOUT ANY OTHER CHECKS ?!

    Did you hear something about XSS? Or other manipulation methods? Absolutely MINIMUM is that you check if the browser is the same as the last valid session – if not, immediately log the user out!

    • Tom
      Author

      I tried to keep the example snippet as easy to understand as possible, due to the difficulty being basix. I’m sorry to have let you down by not providing more in-dept security features. I will write more tutorials though, including advanced ones which I think you might like. Thanks for replying!

      • Patrick

        Yeah okay – but, this is really essential even it’s a basic explaination. Or just a note: “Don’t use this code in production, wait until next tutorial where i talk about security” or something else.

        For me, i think security is really essential basic knowledge. And you already talk about security – escaping mysql query. So for me it’s not understandable why you don’t say anything about checking more parameters to log in a user.

        Bit, I was a bit too directly, sorry for that ;)

  • http://taylorhutchison.com Taylor Hutchison

    Cool. thanks for doing this research! I’d like to see a follow up with more security information. Security is one of my top three interests these days.

  • http://www.eclipsedesign.eu/ Kartlos Tchavelachvili

    Very understandable/clear explanation, nice tut. Thanks!

  • http://ozh.org/ Ozh

    Best practice: always check for headers_sent() before setting cookies

    • Tom
      Author

      Thank you for your additional information!

  • Sebastian

    The PHP example was horribly well down HTML before the PHP closing tag? And it could have been summed up to this:

    • Tom
      Author

      The goal of the PHP snippet was to show people how to use the cookie syntax, and not how to output text. However, you are right and I appreciate your feedback alot!

  • http://www.jordanwalker.net Jordan Walker

    That is a great article on a topic that has major impacts.

  • Peter C

    Readers, please note that some of the code contains silly syntax errors; I’m not sure whether they’re the result of the author’s mistakes or the authoring system (plugins? interfering, but the code is a mess. Until the errors get fixed here, don’t assume every code snippet in the article will work if you copy/paste it.

    • Tom
      Author

      The ‘s being replaced with “s is indeed the fault of a bug in the publishing mechanism. I have not sent the tutorial with these weird repetitive errors in it. It will be fixed asap.

  • Cags

    I’m not being funny (or maybe I am?), but what is with the serious amounts of ‘FAIL’ with regards to strings in your code sections. This is not the first article I’ve noticed it in either. In the last code block of this article, of the 6 strings in the snippet, 5 of them are incorrect. Is this an issue with system used to post them?

    If it is;
    a.) How come one double quote string came out OK, along with the single quoted strings in the other blocks.
    b.) For a site dedicated to coding help (and makes money from it no less), don’t you think it should be fixed?

    If it isn’t;
    a.) WTF.

    • Tom
      Author

      As I’ve replied before, it is indeed a fault of the publishing mechanism, and it will be fixed soon. Thanks for your feedback!

  • http://www.demogeek.com/2009/09/01/automatically-clean-up-your-itunes-library-with-tidysongs/ DemoGeek

    Is there a way to append information to an already existing cookie?

    • Patrick

      Mh, on-the-fly? Not really – in this case you have to read out the cookie with javascript, append your data and write it with javascript into this cookie – the old cookie will be overwrited.

      You can also do so with PHP – but: Here you need to redirect the user after setting the cookie, if you want to access the cookie on the same page. In fact: With PHP you need minimum 1 page request to set the data, another one to get the data.

  • http://www.xboxgamertag.com Gamertag

    Thanks for the tutorial i was just looking for a cookies one as i wanted to do something to a “remember me” :D

  • Tanmay

    Nice to refresh skill set!!!

  • http://www.twitter.com/mamunabms Abdullah Al Mamun

    Good explaination! Thanks for sharing. :-)
    Will love to see more post on PHP tagged ‘BASIX’.

  • Tom
    Author

    Im sorry guys, something has been messed up with the Remember me script, causing all starting ‘s to be “s. I will have this fixed asap.

  • Ihti

    This is cool!!!

  • Xynku

    10x man, some new staff i didnt know

  • http://wwebz.com Anjum

    Hey

    very good and details post Thanks. BWT i am feeling hungry need some real cookies :)

  • Bala

    Great :)

  • Hitesh Chavda

    Yes, We need such article on Nettus, Great Man!

  • Tom
    Author

    The apostrophe issues have now been solved. :)

  • Washington

    Can you tell me what’s the difference between cookies and sessions? and What is safer?

    • Tom
      Author

      Firstly, I am going to write a tutorial about sessions soon, so I hope you´ll check it out. Secondly to answer your question: sessions are variables which are stored on the server, whereas cookies are stored client-side. The differences and advantages will be discussed in my tutorial.

      • http://newleafinternet.com Ben

        Awesome – I appreciate the cookies, but really missed the compare and contrast against sessions. I’m thrilled to hear you’ll be coming back to that, I’m looking forward to it!

  • http://wildanr05.student.ipb.ac.id wildanr

    i’m always wondering, how to edit cookie content in our own computer?

    • Tom
      Author

      FireBug has a nice add-on for viewing and editing cookies. You should look it up on mozilla.com :)

  • http://tgoden.com/ Abhilash Thekkel

    This is interesting… Never knew what cookies were, but i always used to delete them.

  • http://www.sundasun.com PC Tech

    Thanks for share cookies tutorial, i plan to use cookies to build search engine with backgrounds like as ask.com

  • http://www.nikoslianeris.gr nikos lianeris

    at last an understandable tutorial about cokies!Great job!! :)

  • http://www.hotmail.com Ricky

    Thanks for the tutorial, That’s quite useful to me!

  • http://websitedesignnotes.blogspot.com lavie

    Nice tut.

  • Aldo

    Very interesting. cookies had already used in other projects but in this tutorial is very important data. Greetings.

  • stupid.kid

    got some detail from this, thanks

  • http://code-spot.net Rick Lamers

    Hey, there’s a jQuery plugin for this to make it easier http://plugins.jquery.com/project/cookie
    And check out my blog about jQuery at http://www.code-spot.net for more tutorials on jQuery!

  • http://peterchondesign.com peter

    Did you know Facebook stores & sends your username and password via cookies?

  • http://www.banjavrdnik.info Banja Vrdnik privatni smeštaj apartmani

    Cokies helping me in my job very much..

  • masi

    nice overview. even for me some points are new. but one thing that just hit my eye is that you say SHA-1 provides excellent security. at best it provides good security. its not “unbreakable” and even if 2^63 kombinations are still alot to crack, its possible in a realistic time. better use SHA-256 or higher.

  • http://halalit.net Heera

    Enjoyed the article very so much.

  • Tom Clement

    Thanks for the article. I found it enlightening.

  • Naghi

    What an elegant tutorial! I understand cookies but it is always a joy to see something so crisply explained. Thank you.

  • http://www.nu-systems.com Kevwe Ogomigo

    Great post. Very insightful.

  • Manish

    Good Work!!

    • http://net.tutsplus.com/tutorials/javascript-ajax/an-introduction-to-cookies/ iou

      c’est le site vraiment utile. . . .

  • http://www.windowstechsupportnow.com Windows Tech Support

    Great article! Great tutorial! Great examples!

  • http://www.c4learn.com/ Pritesh

    This is awesome tutorial…I really enjoyed reading your tutorial… I was looking for this only from long time…today i found it … :) :)

  • http://www.isolsystems.com/ Ghulam Mustafa

    Really awesome tutorial on cookies. I gain a lot of knowledge that is not available on w3schools or tizag’s tutorials. Thanks a bunch

  • Muhammad Yaqoob

    Well explained, thank you Tom

  • vandana srivastava

    Fantastic tutorial Tom !! Keep it up

  • Slavcho

    Great tutorial. I believe there’s a typo in the first javascript example tho. Shouldn’t it be

    document.cookie = ‘cookiename=cookievalue; expires=’ + expiredate.toUTCString() + ‘; path=/example/; domain=test.envato.com’; // (a semicolon before the “path”)

    instead of

    document.cookie = ‘cookiename=cookievalue; expires=’ + expiredate.toUTCString() + ‘path=/example/; domain=test.envato.com’;