raspberryGPIOhtmlserver/node_modules/connect/lib/middleware/cookieSession.js
node_modules/connect/lib/middleware/cookieSession.jsRaw
1
2/*!
3 * Connect - cookieSession
4 * Copyright(c) 2011 Sencha Inc.
5 * MIT Licensed
6 */
7
8/**
9 * Module dependencies.
10 */
11
12var utils = require('./../utils')
13 , Cookie = require('./session/cookie')
14 , debug = require('debug')('connect:cookieSession')
15 , signature = require('cookie-signature')
16 , crc32 = require('buffer-crc32');
17
18/**
19 * Cookie Session:
20 *
21 * Cookie session middleware.
22 *
23 * var app = connect();
24 * app.use(connect.cookieParser());
25 * app.use(connect.cookieSession({ secret: 'tobo!', cookie: { maxAge: 60 * 60 * 1000 }}));
26 *
27 * Options:
28 *
29 * - `key` cookie name defaulting to `connect.sess`
30 * - `secret` prevents cookie tampering
31 * - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }`
32 * - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto")
33 *
34 * Clearing sessions:
35 *
36 * To clear the session simply set its value to `null`,
37 * `cookieSession()` will then respond with a 1970 Set-Cookie.
38 *
39 * req.session = null;
40 *
41 * @param {Object} options
42 * @return {Function}
43 * @api public
44 */
45
46module.exports = function cookieSession(options){
47 // TODO: utilize Session/Cookie to unify API
48 options = options || {};
49 var key = options.key || 'connect.sess'
50 , trustProxy = options.proxy;
51
52 return function cookieSession(req, res, next) {
53
54 // req.secret is for backwards compatibility
55 var secret = options.secret || req.secret;
56 if (!secret) throw new Error('`secret` option required for cookie sessions');
57
58 // default session
59 req.session = {};
60 var cookie = req.session.cookie = new Cookie(options.cookie);
61
62 // pathname mismatch
63 if (0 != req.originalUrl.indexOf(cookie.path)) return next();
64
65 // cookieParser secret
66 if (!options.secret && req.secret) {
67 req.session = req.signedCookies[key] || {};
68 req.session.cookie = cookie;
69 } else {
70 // TODO: refactor
71 var rawCookie = req.cookies[key];
72 if (rawCookie) {
73 var unsigned = utils.parseSignedCookie(rawCookie, secret);
74 if (unsigned) {
75 var originalHash = crc32.signed(unsigned);
76 req.session = utils.parseJSONCookie(unsigned) || {};
77 req.session.cookie = cookie;
78 }
79 }
80 }
81
82 res.on('header', function(){
83 // removed
84 if (!req.session) {
85 debug('clear session');
86 cookie.expires = new Date(0);
87 res.setHeader('Set-Cookie', cookie.serialize(key, ''));
88 return;
89 }
90
91 delete req.session.cookie;
92
93 // check security
94 var proto = (req.headers['x-forwarded-proto'] || '').toLowerCase()
95 , tls = req.connection.encrypted || (trustProxy && 'https' == proto)
96 , secured = cookie.secure && tls;
97
98 // only send secure cookies via https
99 if (cookie.secure && !secured) return debug('not secured');
100
101 // serialize
102 debug('serializing %j', req.session);
103 var val = 'j:' + JSON.stringify(req.session);
104
105 // compare hashes, no need to set-cookie if unchanged
106 if (originalHash == crc32.signed(val)) return debug('unmodified session');
107
108 // set-cookie
109 val = 's:' + signature.sign(val, secret);
110 val = cookie.serialize(key, val);
111 debug('set-cookie %j', cookie);
112 res.setHeader('Set-Cookie', val);
113 });
114
115 next();
116 };
117};