Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express session with different cookie domain per request?

I have a situation where an app can be accessed from multiple different domains. For instance, foo.com and bar.com could both in theory point to my app. Additionally, their subdomains can also point to my app, so for instance red.foo.com and blue.foo.com. I'm using Express cookie sessions, and my initialization code for the session looks like that:

app.use(express.session({
    secret: "secret",
    cookie: {
        domain: ".foo.com"
    },
    store: new MongoStore({
        db: db
    })
}));

That works well for when users go through foo.com or any of it's subdomains, but bar.com won't work. I need to have both at once. Ideally, I would set it to a different domain per request, but I'm not sure how I would do that. My requests are highly asynchronous and if I just set it for the whole app at every request, I fear it might not work when two calls come in at once.

Is this at all possible? Does anyone have any ideas to solve this?

like image 615
Alex Turpin Avatar asked Sep 30 '13 21:09

Alex Turpin


People also ask

Can cookie have 2 domains?

As you may know, cookie can't be set in a different domain from another domain directly. If you're having multiple sites in where you need to set a cookie from a parent site, you can use basic HTML and JS to set the cookies. Google is using this same way.

What is the difference between Express-session and cookie session?

express-session stores session data into configurable backends, ranging from memory to any number of databases, thus allowing essentially unlimited session storage. cookie-session stores session data into cookies, thus being limited to a bit under 4k bytes of session storage.

How does express cookie session work?

How sessions works. When the client makes a login request to the server, the server will create a session and store it on the server-side. When the server responds to the client, it sends a cookie. This cookie will contain the session's unique id stored on the server, which will now be stored on the client.

How do you set an express-session cookie?

var cookieSession = require('cookie-session') var express = require('express') var app = express() app. use(cookieSession({ name: 'session', keys: ['key1', 'key2'] })) // Update a value in the cookie so that the set-cookie will be sent. // Only changes every minute so that it's not sent with every request.


1 Answers

Here's what you do:

  • write a middleware your app can use in place of the default express.session middleware
  • in that middleware, based on the host request header instatiate and configure on instance of the express session middleware per domain, and then actually execute the middleware function appropriate for this request

pseudocode

var mwCache = Object.create(null);
function virtualHostSession(req, res, next) {
  var host = req.get('host'); //maybe normalize with toLowerCase etc
  var hostSession = mwCache[host];
  if (!hostSession) {
    hostSession = mwCache[host] = express.session(..config for this host...);
  }
  hostSession(req, res, next);
  //don't need to call next since hostSession will do it for you
}

app.use(virtualHostSession);

My requests are highly asynchronous and if I just set it for the whole app at every request, I fear it might not work when two calls come in at once.

Absolutely you cannot do that. It will be utterly incorrect.

like image 144
Peter Lyons Avatar answered Oct 12 '22 22:10

Peter Lyons