Search code examples
sslconnect-mongocompose-db

How to connect to a `mongos` instance over TLS/SSL using `connect-mongo` for `express-session`?


I use connect-mongo as the storage module for express-session, and all was working well until I switched to the new 'MongoDB+' TLS/SSL deployment from Compose.io, and now I can't connect.

I don't know their architecture in detail, but more information can be found here: Bringing SSL To Compose MongoDB

And here: Going SSL With Compose MongoDB+

And here: One Missing Key and How It Broke Node.js

I do know that when you connect you need to declare mongos options and your connection code ends up looking like so:

var fs = require('fs');
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);

var ca = [fs.readFileSync('./Mongo-Key.pem')];

var url = 'mongodb://MY_MONGO_USER:MY_MONGO_PASS@mongos1.compose.io:12345,mongos2.compose.io:54321/Sessions';

app.use(session({
    key : 'SessionKey',
    secret : 'CATONTHEKEYBOARD',
    cookie : {
        path : '/',
        httpOnly : true,
        maxAge : null
    },
    store : new MongoStore({
        url : url,
        mongoOptions : {
            mongos : {
                ssl : true,
                sslValidate : true,
                sslCA : ca,
                ca : ca, 
                poolSize : 1,
                reconnectTries : 1
            }
        },
        collection : 'sessions',
        stringify : false
    }, function(result) {

        console.log('Connected to sessions db!');
        return next();

    })
}));

That connection string, along with those connection options, works using the mongo-native driver. I can connect and perform all operations.

But applying them in this context produces ... nothing. It just hangs.

Any idea how I could go about producing any output to further debug?

Thanks for any help!


Solution

  • Well, as it turns out connect-mongo removed the second argument (the one I was trying to use as a callback) in the more recent versions. So the problem was that my callback was never being called.

    Adjusting the code like follows is what worked:

    var fs = require('fs');
    var session = require('express-session');
    var MongoStore = require('connect-mongo')(session);
    
    var ca = [fs.readFileSync('./Mongo-Key.pem')];
    
    var url = 'mongodb://MY_MONGO_USER:MY_MONGO_PASS@mongos1.compose.io:12345,mongos2.compose.io:54321/Sessions';
    
    app.use(session({
        key : 'SessionKey',
        secret : 'CATONTHEKEYBOARD',
        cookie : {
            path : '/',
            httpOnly : true,
            maxAge : null
        },
        store : new MongoStore({
            url : url,
            mongoOptions : {
                mongos : {
                    ssl : true,
                    sslValidate : true,
                    sslCA : ca,
                    ca : ca, 
                    poolSize : 1,
                    reconnectTries : 1
                }
            },
            collection : 'sessions',
            stringify : false
        }).on('connected', function(result) {
    
            console.log('Connected to sessions db!');
            return next();
    
        })
    }));