diff --git a/README.md b/README.md index 70f8f2be..b0482da4 100644 --- a/README.md +++ b/README.md @@ -280,6 +280,34 @@ The default value is `'keep'`. - `'keep'` The session in the store will be kept, but modifications made during the request are ignored and not saved. + +##### getcookie, setcookie + +Allows to specify custom functions to parse and set cookies. + +Warnings: + - cookies must be parsed accordingly to how they are set of course + - the function signatures are subject to change in the future + +```js +app.use(session({ + name: sessionKey, + secret: sessionSecret, + getcookie(req) { // full signature is (req, name, secrets) + var cookies = cookie.parse(headers.cookie || headers.authorization || ''); + return signature.unsign(cookies[sessionKey] || '', sessionSecret); + }, + setcookie(res, name, val, secret, options) { + var signed = signature.sign(val, sessionSecret); + var data = cookie.serialize(sessionKey, signed, options); + res.setHeader('set-cookie', data); + res.setHeader('Access-Control-Expose-Headers', 'Authorization'); + res.setHeader('authorization', data); + }, + secret: 'keyboard cat' +})) +``` + ### req.session To store or access session data, simply use the request property `req.session`, diff --git a/index.js b/index.js index 68ccf533..321f038b 100644 --- a/index.js +++ b/index.js @@ -110,6 +110,10 @@ function session(options) { // get the save uninitialized session option var saveUninitializedSession = opts.saveUninitialized + // get optional getcookie and setcookie custom functions + var getcookie = opts.getcookie || getcookieDefault; + var setcookie = opts.setcookie || setcookieDefault; + // get the cookie signing secret var secret = opts.secret @@ -509,7 +513,7 @@ function generateSessionId(sess) { * @private */ -function getcookie(req, name, secrets) { +function getcookieDefault(req, name, secrets) { var header = req.headers.cookie; var raw; var val; @@ -631,7 +635,7 @@ function issecure(req, trustProxy) { * @private */ -function setcookie(res, name, val, secret, options) { +function setcookieDefault(res, name, val, secret, options) { var signed = 's:' + signature.sign(val, secret); var data = cookie.serialize(name, signed, options); diff --git a/test/getcookie.js b/test/getcookie.js new file mode 100644 index 00000000..5ecf61ee --- /dev/null +++ b/test/getcookie.js @@ -0,0 +1,74 @@ +'use strict'; +process.env.NO_DEPRECATION = 'express-session'; + +var after = require('after') +var assert = require('assert') +var express = require('express') + , request = require('supertest') + , cookieParser = require('cookie-parser') + , session = require('../') + , Cookie = require('../session/cookie') +var fs = require('fs') +var http = require('http') +var https = require('https') +var util = require('util') +var cookie = require('cookie') +var signature = require('cookie-signature') + +var min = 60 * 1000; + +describe('session getcookie()', function(){ + + var sessionKey = 'foo'; + var sessionSecret = 'bar'; + + var app = express() + .use(session({ + name: sessionKey, + secret: sessionSecret, + getcookie: function(req) { + var cookies = cookie.parse(req.headers.authorization || ''); + return signature.unsign(cookies[sessionKey] || '', sessionSecret); + }, + setcookie: function(res, name, val, secret, options) { + var signed = signature.sign(val, secret); + var data = cookie.serialize(name, signed, options); + // res.setHeader('Access-Control-Expose-Headers', 'Authorization'); necessary with cors + res.setHeader('authorization', data); + } + })) + .post('/', function(req, res) { + req.session.user = 'John'; + return res.json({ok: 1}) + }) + .get('/', function(req, res) { + res.json({user: req.session.user}); + }); + + + var data; + + it('should set a session, and send it in authorization header', function(done){ + + request(app) + .post('/') + .expect(function (res) { + data = res.headers.authorization; + }) + .expect(200, done) + }) + + it('should get the session using authorization header', function(done){ + + request(app) + .get('/') + .set('Authorization', data) + .expect(function (res) { + assert.equal(res.body.user, 'John') + }) + .expect(200, done) + + }) + +}) + diff --git a/test/session.js b/test/session.js index e0c97d60..429fedf9 100644 --- a/test/session.js +++ b/test/session.js @@ -2084,6 +2084,8 @@ describe('session()', function(){ }) }) + + function cookie(res) { var setCookie = res.headers['set-cookie']; return (setCookie && setCookie[0]) || undefined;