Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ test-travis:
$(TESTS)

autod:
@./node_modules/.bin/autod -w -e example --prefix=~ --keep=supertest,debug
@./node_modules/.bin/autod -w -e example --prefix=~ --keep=supertest,debug, --semver=koa@1
@$(MAKE) install

.PHONY: test
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ app.listen(8080);
* `errorHandler(err, type, ctx)`: `Store.get` and `Store.set` will throw in some situation, use `errorHandle` to handle these errors by yourself. Default will throw.
* `reconnectTimeout`: When store is disconnected, don't throw `store unavailable` error immediately, wait `reconnectTimeout` to reconnect, default is `10s`.
* `sessionIdStore`: object with get, set, reset methods for passing session id throw requests.
* `valid`: valid(ctx, session), valid session value before use it
* `beforeSave`: beforeSave(ctx, session), hook before save session

* Store can be any Object that has the methods `set`, `get`, `destroy` like [MemoryStore](https://github.com/koajs/koa-session/blob/master/lib/store.js).
* cookie defaulting to
Expand All @@ -122,6 +124,11 @@ if you set`cookie.maxage` to `null`, meaning no "expires" parameter is set so th
Notice that `ttl` is different from `cookie.maxage`, `ttl` set the expire time of sessionStore. So if you set `cookie.maxage = null`, and `ttl=ms('1d')`, the session will expired after one day, but the cookie will destroy when the user closes the browser.
And mostly you can just ignore `options.ttl`, `koa-generic-session` will parse `cookie.maxage` as the tll.

## Hooks

- `valid()`: valid session value before use it
- `beforeSave()`: hook before save session

## Session Store

You can use any other store to replace the default MemoryStore, it just needs to follow this api:
Expand Down
17 changes: 15 additions & 2 deletions lib/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ const defaultCookie = {
* you should `yield this.session` to get the session if defer is true, default is false
* - [`genSid`] you can use your own generator for sid
* - [`errorHanlder`] handler for session store get or set error
* - [`valid`] valid(ctx, session), valid session value before use it
* - [`beforeSave`] beforeSave(ctx, session), hook before save session
* - [`sessionIdStore`] object with get, set, reset methods for passing session id throw requests.
*/

Expand All @@ -67,6 +69,8 @@ module.exports = function (options) {
});

let genSid = options.genSid || uid.sync;
let valid = options.valid || noop;
let beforeSave = options.beforeSave || noop;

let cookie = options.cookie || {};
copy(defaultCookie).to(cookie);
Expand Down Expand Up @@ -184,8 +188,10 @@ module.exports = function (options) {
}
}

if (!session) {
debug('can not get with key:%s from session store, generate a new one', this.sessionId);
// make sure the session is still valid
if (!session ||
!valid(this, session)) {
debug('session is empty or invalid');
session = generateSession();
this.sessionId = genSid.call(this, 24);
sessionIdStore.reset.call(this);
Expand Down Expand Up @@ -232,6 +238,9 @@ module.exports = function (options) {
debug('session modified');
compatMaxage(session.cookie);

// custom before save hook
beforeSave(this, session);

//update session
try {
yield store.set(this.sessionId, session);
Expand Down Expand Up @@ -387,3 +396,7 @@ function defaultErrorHanlder (err, type, ctx) {
err.name = 'koa-generic-session ' + type + ' error';
throw err;
}

function noop () {
return true;
}
20 changes: 12 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,29 @@
"description": "koa generic session store by memory, redis or others",
"repository": "koajs/generic-session",
"version": "1.9.2",
"keywords": ["koa", "middleware", "session"],
"keywords": [
"koa",
"middleware",
"session"
],
"author": "dead_horse <dead_horse@qq.com>",
"dependencies": {
"copy-to": "~2.0.1",
"crc": "~3.2.1",
"crc": "~3.3.0",
"debug": "*",
"parseurl": "~1.3.0",
"uid-safe": "~1.0.1"
"uid-safe": "~2.0.0"
},
"devDependencies": {
"autod": "~0.3.0",
"autod": "~2.1.3",
"blanket": "*",
"contributors": "*",
"istanbul-harmony": "*",
"koa": "~0.13.0",
"koa-redis": "*",
"mm": "~1.0.1",
"koa": "~1.1.2",
"koa-redis": "~1.0.1",
"mm": "~1.3.5",
"mocha": "2",
"should": "~4.3.0",
"should": "~7.1.1",
"supertest": "~0.13.0"
},
"engines": {
Expand Down
27 changes: 25 additions & 2 deletions test/session.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ var EventEmitter = require('events').EventEmitter;
describe('test/koa-session.test.js', function () {
describe('init', function () {
afterEach(mm.restore);

beforeEach(function (done) {
request(app)
.get('/session/remive')
.expect(200, done);
});

it('should warn when in production', function (done) {
mm(process.env, 'NODE_ENV', 'production');
mm(console, 'warn', function (message) {
Expand Down Expand Up @@ -157,7 +164,23 @@ describe('test/koa-session.test.js', function () {
it('should rewrite session before get ok', function (done) {
request(app)
.get('/session/rewrite')
.expect({foo: 'bar'}, done);
.expect({foo: 'bar', path: '/session/rewrite'}, done);
});

it('should regenerate a new session when session invalid', function (done) {
request(app)
.get('/session/get')
.expect('1', function (err) {
should.not.exist(err);
request(app)
.get('/session/nothing?valid=false')
.expect('', function (err) {
should.not.exist(err);
request(app)
.get('/session/get')
.expect('1', done);
});
});
});

it('should GET /session ok', function (done) {
Expand Down Expand Up @@ -195,7 +218,7 @@ describe('test/koa-session.test.js', function () {
});
});

it('should regenerate new sessions', function (done) {
it('should regenerate a new session', function (done) {
request(app)
.get('/session/regenerateWithData')
.expect({ /* foo: undefined, */ hasSession: true }, done);
Expand Down
6 changes: 6 additions & 0 deletions test/support/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ app.use(session({
genSid: function(len) {
return uid(len) + this.request.query.test_sid_append;
},
beforeSave: function (ctx, session) {
session.path = ctx.path;
},
valid: function (ctx, session) {
return ctx.query.valid !== 'false';
},
reconnectTimeout: 100
}));

Expand Down