npm

client-sessionspublic

client-sessions is connect middleware that implements sessions in encrypted tamper-free cookies. For a complete introduction to encrypted client side sessions, refer to Francois Marier's blog post on the subject;

NOTE: It is not recommended using both this middleware and connect's built-in session middleware.

Installation

npm install client-sessions

Usage

Basic usage:

var sessions =require("client-sessions");

app.use(sessions({

cookieName:'mySession',// cookie name dictates the key name added to the request object

secret:'blargadeeblargblarg',// should be a large unguessable string

duration:24*60*60*1000,// how long the session will stay valid in ms

activeDuration:1000*60*5// if expiresIn < activeDuration, the session will be extended by activeDuration milliseconds

}));

app.use(function(req,res,next){

if(req.mySession.seenyou){

res.setHeader('X-Seen-You','true');

}else{

// setting a property will automatically cause a Set-Cookie response

// to be sent

req.mySession.seenyou=true;

res.setHeader('X-Seen-You','false');

}

});

You can control more specific cookie behavior during setup:

app.use(sessions({

cookieName:'mySession',// cookie name dictates the key name added to the request object

secret:'blargadeeblargblarg',// should be a large unguessable string

duration:24*60*60*1000,// how long the session will stay valid in ms

cookie:{

path:'/api',// cookie will only be sent to requests under '/api'

maxAge:60000,// duration of the cookie in milliseconds, defaults to duration above

ephemeral:false,// when true, cookie expires when the browser closes

httpOnly:true,// when true, cookie is not accessible from javascript

secure:false// when true, cookie will only be sent over SSL. use key 'secureProxy' instead if you handle SSL not in your node process

}

}));

You can have multiple cookies:

// a 1 week session

app.use(sessions({

cookieName:'shopping_cart',

secret:'first secret',

duration:7*24*60*60*1000

}));

// a 2 hour encrypted session

app.use(sessions({

cookieName:'authenticated',

secret:'first secret',

duration:2*60*60*1000

}));

In this example, there's a 2 hour authentication session, but shopping carts persist for a week.

Finally, you can use requestKey to force the name where information can be accessed on the request object.

var sessions =require("client-sessions");

app.use(sessions({

cookieName:'mySession',

requestKey:'forcedSessionKey',// requestKey overrides cookieName for the key name added to the request object.

secret:'blargadeeblargblarg',// should be a large unguessable string or Buffer

duration:24*60*60*1000,// how long the session will stay valid in ms

}));

app.use(function(req,res,next){

// requestKey forces the session information to be

// accessed via forcedSessionKey

if(req.forcedSessionKey.seenyou){

res.setHeader('X-Seen-You','true');

}

next();

});

Cryptography

A pair of encryption and signature keys are derived from the secret option
via HMAC-SHA-256; the secret isn't used directly to encrypt or compute the
MAC.

The key-derivation function, in pseudocode:

encKey := HMAC-SHA-256(secret, 'cookiesession-encryption');

sigKey := HMAC-SHA-256(secret, 'cookiesession-signature');

The AES-256-CBC cipher is used to encrypt the session contents, with an
HMAC-SHA-256 authentication tag (via Encrypt-then-Mac composition). A
random 128-bit Initialization Vector (IV) is generated for each encryption
operation (this is the AES block size regardless of the key size). The
CBC-mode input is padded with the usual PKCS#5 scheme.

In pseudocode, the encryption looks like the following, with || denoting
concatenation. The createdAt and duration parameters are decimal strings.