Objectives |
---|
Review the request and response cycle and the stateless web |
Discuss and use an HTTP Cookie in a web application |
Differentiate between an HTTP Cookie and a session |
An HTTP cookie is a small piece of data sent from a website and stored in a user's web browser. Every time the user loads the website, the browser sends the cookie back to the server in the HTTP Request Header. Cookies are commonly used to track whether a user is logged in or not. They can also be used to record user preferences.
Our goal today is to harness the power of cookies. First, to track users to our website. And secondly, to track their login "session".
Writing Cookies:
var express = require("express");
var app = express();
app.get("/", function (req, res) {
// write the HTTP Cookie to the Response Header
res.set({
"Set-Cookie": "message=hello"
});
res.send("Hello World");
});
app.listen(3000, function () {
console.log("UP AND RUNNING");
});
Reading Cookies (from inside any route):
// read the HTTP Cookie from Request Header
var cookieStr = req.get("Cookie");
In practice we'll use cookie-parser
middleware to so that we don't have to deal with string manipulation, and can just manipulate an object of key-value pairs. (We did the same thing with body-parser
middleware).
First we have to install cookie-parser
:
npm install --save cookie-parser
And now we just tell our app to use cookie-parser
.
var express = require('express');
var cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser());
Altogether that looks like:
var express = require('express');
var cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser());
app.get("/", function (req, res) {
console.log(req.cookie.message); // "hello"
res.cookie("message", "hello again"); // overwrite
res.send("Hello World");
});
app.listen(3000, function () {
console.log("UP AND RUNNING");
});
HTTP Response Header
This sends a response that looks something like the following:
HTTP/1.1 200 OK
X-Powered-By: Express
Set-Cookie: message=hello%20again
Content-Type: text/html; charset=utf-8
Content-Length: 11
ETag: W/"b-4a17b156"
Date: Mon, 18 May 2015 07:36:50 GMT
Connection: keep-alive
Hello World
The Cookie is then saved to the browser for localhost:3000. You can view it in the Chrome Developer Console under the "resources" tab. Try this.
Once the cookie is set in the browser, any subsequent request to the website automatically has the following line in the HTTP Request Header:
...
cookie: 'message=hello',
...
It's also possible to manipulate cookies on the client-side.
From the Chrome Developer Console:
document.cookie; // "message=hello"
You can write to this string simply by reassigning its value. Take care though that you don't overwrite anything important (and watch out for spaces and semi-colons)!
document.cookie += "; magic_number=10;"
document.cookie; // "message=hello; magic_humber=10;"
Try it out! Open your Console, and see what cookies are set in your browser. Try it out on a few different websites.
- Can you create a new cookie.
- Can you overwrite an existing cookie.
- Can you add a key-value pair to an existing cookie.
- Can you log yourself out of a website by deleting your cookie (and refreshing the page)?
For more on this approach, take a look at Quirksmode on Cookies.
Additional reading:
- Cookies in the Chrome Console
- HTTP Intro
- An Introduction to Cookies (php/javascript)
Cookies are great, but they're limited in size, and they're hard to work with. If we want finer control, we want sessions!
Imagine for a moment that we have a fancy quiz-app and we used cookies to store user preferences and the current state of the quiz. Eventually the request header might look like:
host: quizful.ly
method: GET
cookie: wrong_answers=7; right_answer=3; current_question=11; GeoIP=US:CA:San_Francisco:37.7909:-122.4017:v4; last_access=31-Aug-2015;
Now imagine that, instead of storing all this data in the browser, the server kept it in a database. And everytime someone visits the website for the first time, they're assigned a globally unique id, or guid.
host: quizful.ly
method: GET
cookie: guid=a134vbce34584ibjeapc38;
Now, instead of needing to read, parse, and manipulate all the data in the cookie, we can just find the user's session based on their guid.
Here's the cheater way of doing this (the real way is using express-session
middleware):
var sessions = {};
// stubbed data
sessions["a134vbce34584ibjeapc38"] = {
wrong_answers: 7,
right_answers: 3,
current_question: 11,
GeoIp: "US:CA:San_Francisco:37.7909:-122.4017:v4",
last_access: "31-Aug-2015"
}
app.get("/quiz", function(){
// sets the guid if none exists
res.set("guid", randomly_generated_unique_identifer)
// adds a new object to the sessions object, above
//...
})
app.post("/answer", function(){
var guid = res.cookies.guid;
var session = sessions[guid];
var answer = res.query.answer;
if ( right_answer ) {
// update session
session.right_answers +=1;
session.current_question +=1;
res.send({verdict: "correct"})
} else {
// update session
session.wrong_answers +=1;
res.send({verdict: "incorrect"})
}
})
Later we'll learn about express-sessions
middleware.