Cookies

  • An HTTP cookie (web cookie, browser cookie) is a small piece of data that a server sends to the user's web browser, that may store it and send it back together with the next request to the same server. See HTTP cookies at MDN
  • Cookies were designed to be a reliable mechanism for websites to remember stateful information
  • They can be used to remember arbitrary pieces of information that the user previously entered into form fields
  • Cookies for Session Management: the server sends a cookie to the client using a set-cookie header. The cookie contains a unique session identifier (typically, a long string of random letters and numbers).
    • Because cookies are sent to the server with every request the client makes, that session identifier will be sent back to the server every time the user visits a new page on the website, which lets the server know which client is
  • Cookies for logging into websites: When the user visits a website's login page, the web server typically sends the client a cookie containing a unique session identifier. When the user successfully logs in, the server remembers that that particular session identifier has been authenticated, and grants the user access to its services.
  • Session cookie: exists only in temporary memory while the user navigates the website. Web browsers normally delete session cookies when the user closes the browser
  • Persistent cookie: expires at a specific date or after a specific length of time.

Ejemplo Simple

Fichero hello-cookie.js

// https://www.codementor.io/noddy/cookie-management-in-express-js-du107rmna
var express = require('express');
var cookieParser = require('cookie-parser');
var util = require('util');

var app = express();
app.use(cookieParser());

app.get('/cookie',function(req, res){
     res.cookie('cookie_name', 'cookie_value', {expire : new Date() + 9999}).send(
       "Cookie is set: goto to browser's console and write document.cookie.");
});

app.get('/', function(req, res) {
  res.send("visit localhost:8080/cookie")
});

app.get('/show', function(req, res) {
  console.log("Cookies :  ", req.cookies);
  res.send("Cookies :  "+util.inspect(req.cookies));
});

app.get('/clearcookie', function(req,res){
     res.clearCookie('cookie_name');
     res.send('Cookie deleted');
});

var server = app.listen(8080, function () {

  var host = server.address().address
  var port = server.address().port

  console.log('Example app listening at http://%s:%s', host, port)

})

Fichero cookie.js

Este ejemplo no hace uso de ExpressJS ni de cookie-parser:

// https://www.npmjs.com/package/cookie
/*
cookie: a npm module for cookie parsing and serialization
*/

var cookie = require('cookie');
var escapeHtml = require('escape-html');
var http = require('http');
var url = require('url');

var form = `
<form method="GET">
  <input placeholder="Enter your name" name="name"> 
  <input type="submit" value="Set Name">
</form>
`;

function onRequest(req, res) {
  console.log(req.url);
  // Parse the query string 
  var query = url.parse(req.url, true, true).query;
  console.log(query);

  if (query && query.name) {
    // Set a new cookie with the name 
    res.setHeader('Set-Cookie', cookie.serialize('name', String(query.name), {
      httpOnly: true,
      maxAge: 60 * 60 * 24 * 7 // 1 week 
    }));

    // Redirect back after setting cookie 
    res.statusCode = 302;
    res.setHeader('Location', req.headers.referer || '/');
    res.end();
    return;
  }

  // Parse the cookies on the request 
  var cookies = cookie.parse(req.headers.cookie || '');

  // Get the visitor name set in the cookie 
  var name = cookies.name;

  res.setHeader('Content-Type', 'text/html; charset=UTF-8');

  if (name) {
    res.write(`<p>Welcome back, <b> ${escapeHtml(name)} </b>!</p>`);
  } else {
    res.write('<p>Hello, new visitor!</p>');
  }

  res.write(form);
  res.end();
}

http.createServer(onRequest).listen(3000);

Recursos

Tutoriales

Cookies y Seguridad

cookieParser(secret, options)

  • secret a string or array used for signing cookies.
    • This is optional and if not specified, will not parse signed cookies.
    • If a string is provided, this is used as the secret.
    • If an array is provided, an attempt will be made to unsign the cookie with each secret in order.
  • options an object that is passed to cookie.parse as the second option. See cookie for more information.
    • decode a function to decode the value of the cookie

HttpOnly

  • HttpOnly is a flag that can be included in a Set-Cookie response header.
  • The presence of this flag will tell browsers to not allow client side script access to the cookie (if the browser supports it).
  • This is important because it helps protect your cookie data from malicious scripts and helps mitigate the most common XSS attacks.
    • Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted web sites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user.
  • Here is how you can tell Express to set your cookie using the HttpOnly flag:
    res.cookie('sessionid', '1', { httpOnly: true });
    

Secure

  • The Secure flag is included in a Set-Cookie response header.
  • The presence of the secure flag tells web browsers to only send this cookie in requests going to HTTPS endpoints.
  • This is very important, as the cookie information will not be sent on an unencrypted channel.
  • This helps mitigate some exploits where your browser is redirected to the HTTP endpoint for a site rather than the HTTPS endpoint and thus potentially exposing your cookies to someone in the middle of the traffic.
  • Here is how you can tell Express to set your cookie using the Secure flag:
    res.cookie('sessionid', '1', { secure: true });
    

Query String

A query string is the part of a uniform resource locator (URL) containing data that does not fit conveniently into a hierarchical path structure. The query string commonly includes fields added to a base URL by a Web browser or other client application, for example as part of an HTML form

Example

If a form is embedded in an HTML page as follows:

<form action="/hello" method="get">
  <input type="text" name="first" />
  <input type="text" name="second" />
  <input type="submit" />
</form>

and the user inserts the strings this is a field and was it clear (already)? in the two text fields and presses the submit button, the handler of the route /hello (the route specified by the action attribute of the form element in the above example) will receive the following query string:

first=this+is+a+field&second=was+it+clear+%28already%29%3F.

If the form is processed on the server by a CGI script, the script may typically receive the query string as an environment variable named QUERY_STRING.

Apuntes en Ruby sobre Cookies