Skip to content

Commit

Permalink
session: add long expires check and prevent set-cookie
Browse files Browse the repository at this point in the history
  • Loading branch information
tj committed Apr 1, 2013
1 parent 3edc728 commit 86c72bd
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 9 deletions.
34 changes: 30 additions & 4 deletions examples/session.js
Expand Up @@ -2,8 +2,34 @@
var connect = require('../')
, http = require('http');

var year = 31557600000;

// large max-age, delegate expiry to the session store.
// for example with connect-redis's .ttl option.

http.createServer(connect()
.use(connect.cookieParser())
.use(connect.session({ secret: 'keyboard cat', cookie: { maxAge: year }}))
.use(connect.favicon())
.use(function(req, res, next){
var sess = req.session;
if (sess.views) {
sess.views++;
res.setHeader('Content-Type', 'text/html');
res.write('<p>views: ' + sess.views + '</p>');
res.write('<p>expires in: ' + (sess.cookie.maxAge / 1000) + 's</p>');
res.end();
} else {
sess.views = 1;
res.end('welcome to the session demo. refresh!');
}
})).listen(3007);

console.log('port 3007: 1 minute expiration demo');


// expire sessions within a minute
// /favicon.ico is ignored, and will not
// /favicon.ico is ignored, and will not
// receive req.session

http.createServer(connect()
Expand All @@ -22,9 +48,9 @@ http.createServer(connect()
sess.views = 1;
res.end('welcome to the session demo. refresh!');
}
})).listen(3000);
})).listen(3006);

console.log('port 3000: 1 minute expiration demo');
console.log('port 3006: 1 minute expiration demo');

// $ npm install connect-redis

Expand All @@ -49,7 +75,7 @@ try {
res.end('welcome to the redis demo. refresh!');
}
})).listen(3001);

console.log('port 3001: redis example');
} catch (err) {
console.log('\033[33m');
Expand Down
6 changes: 5 additions & 1 deletion lib/middleware/session.js
Expand Up @@ -256,6 +256,9 @@ function session(options){
// only send secure cookies via https
if (cookie.secure && !secured) return debug('not secured');

// long expires, handle expiry server-side
if (!isNew && cookie.hasLongExpires) return debug('already set cookie');

// browser-session length cookie
if (null == cookie.expires) {
if (!isNew) return debug('already set browser-session cookie');
Expand All @@ -277,7 +280,8 @@ function session(options){
if (!req.session) return res.end(data, encoding);
debug('saving');
req.session.resetMaxAge();
req.session.save(function(){
req.session.save(function(err){
if (err) console.error(err.stack);
debug('saved');
res.end(data, encoding);
});
Expand Down
20 changes: 16 additions & 4 deletions lib/middleware/session/cookie.js
Expand Up @@ -43,7 +43,7 @@ Cookie.prototype = {
* @param {Date} date
* @api public
*/

set expires(date) {
this._expires = date;
this.originalMaxAge = this.maxAge;
Expand All @@ -59,14 +59,14 @@ Cookie.prototype = {
get expires() {
return this._expires;
},

/**
* Set expires via max-age in `ms`.
*
* @param {Number} ms
* @api public
*/

set maxAge(ms) {
this.expires = 'number' == typeof ms
? new Date(Date.now() + ms)
Expand Down Expand Up @@ -104,6 +104,18 @@ Cookie.prototype = {
}
},

/**
* Check if the cookie has a reasonably large max-age.
*
* @return {Boolean}
* @api private
*/

get hasLongExpires() {
var week = 604800000;
return this.maxAge > (4 * week);
},

/**
* Return a serialized cookie string.
*
Expand All @@ -121,7 +133,7 @@ Cookie.prototype = {
* @return {Object}
* @api private
*/

toJSON: function(){
return this.data;
}
Expand Down

1 comment on commit 86c72bd

@valentinkostadinov
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check for hasLongExpires (4 weeks) seems buggy. It stops us from being able to implement a "rollng session" with maxAge of more than 4 weeks.
Say we want to implement a "rolling session" with maxAge of 3 months. We hack the "rolling session" by updating the session object. But still the cookie is never updated in the browser. Not until there's 4 weeks left. So if the user is active for two months and the stops, his session will be good for only another 4 weeks, instead of 3 months as one would expect.

Please sign in to comment.