Skip to content

Commit

Permalink
add getDomainFromRequest option, for when domain needs to be calculated
Browse files Browse the repository at this point in the history
This adds a `getDomainFromRequest` option which allows `cookie.domain`
to be computed from the request rather than set as a constant.
As an example of when this is useful, imagine serving a single app
from `*.foo.com` and `*.bar.com`, with domain being `.foo.com` for the
`*.foo.com` domains and `.bar.com` for the `*.bar.com` domains.

This may be related to expressjs#311
  • Loading branch information
paulfitz committed Apr 22, 2020
1 parent 3b08fc7 commit c31d25a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 0 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,18 @@ app.use(session({
}))
```

##### getDomainFromRequest

Optional function to override the `Domain` `Set-Cookie` attribute.
Provide a function that returns a string that will be used as the
cookie domain. The function is given `req` as the first argument if
you want to use some value attached to `req` when generating the
domain (as for `genid`). This can be useful if the same app is
accessed from different families of domains, some of which should
share cookies.

If this function is not provided, `cookie.domain` is used instead.

##### name

The name of the session ID cookie to set in the response (and read from in the
Expand Down
13 changes: 13 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,17 @@ function session(options) {
// get the cookie signing secret
var secret = opts.secret

// get a function for computing the domain from the request
var getDomainFromRequest = opts.getDomainFromRequest

if (typeof generateId !== 'function') {
throw new TypeError('genid option must be a function');
}

if (getDomainFromRequest !== undefined && typeof getDomainFromRequest !== 'function') {
throw new TypeError('getDomainFromRequest option must be a function');
}

if (resaveSession === undefined) {
deprecate('undefined resave option; provide resave option');
resaveSession = true;
Expand Down Expand Up @@ -160,6 +167,12 @@ function session(options) {
req.session = new Session(req);
req.session.cookie = new Cookie(cookieOptions);

if (getDomainFromRequest) {
// If a function was specified for computing the domain
// from the request, then use it now.
req.session.cookie.domain = getDomainFromRequest(req);
}

if (cookieOptions.secure === 'auto') {
req.session.cookie.secure = issecure(req, trustProxy);
}
Expand Down
31 changes: 31 additions & 0 deletions test/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,37 @@ describe('session()', function(){
});
});

describe('getDomainFromRequest option', function(){
it('should reject non-function values', function(){
assert.throws(session.bind(null, { getDomainFromRequest: 'bogus!' }), /getDomainFromRequest.*must/)
});

it('should work without getDomainFromRequest', function(done){
request(createServer())
.get('/')
.expect(shouldSetCookie('connect.sid'))
.expect(200, done)
});

it('should allow custom domain', function(done){
function getDomainFromRequest(req) { return '.do.main' }

request(createServer({ getDomainFromRequest: getDomainFromRequest }))
.get('/')
.expect(shouldSetCookieWithAttributeAndValue('connect.sid', 'Domain', '.do.main'))
.expect(200, done)
});

it('should provide req argument', function(done){
function getDomainFromRequest(req) { return req.url }

request(createServer({ getDomainFromRequest: getDomainFromRequest }))
.get('/foo')
.expect(shouldSetCookieWithAttributeAndValue('connect.sid', 'Domain', '/foo'))
.expect(200, done)
});
});

describe('key option', function(){
it('should default to "connect.sid"', function(done){
request(createServer())
Expand Down

0 comments on commit c31d25a

Please sign in to comment.