1

My MongoDB has a sessions collection that is created by a module. The collection has no model or anything since it is not created by Mongoose.

How can I access this collection without specifying it's model?

I tried the following:

mongoose.connection.db.sessions.remove({'session.userId': userId}, function(e, found) {
    console.log(found);
    res.json({success: true});
});

Although I received the error of: Cannot read property 'remove' of undefined

Fizzix
  • 23,679
  • 38
  • 110
  • 176
  • Possible duplicate http://stackoverflow.com/a/10519504/3284355 see the edit of correct answer. You can use mongo native driver package since it's already installed – Molda Jun 25 '16 at 05:58

1 Answers1

2

Querying the collection directly will only solve part of your problem.

From the looks of it, you're using express-session and connect-mongo to manage sessions. This will store the session data (req.session) as a JSON string in the database:

{
  "_id": "fLBj_McMFM-7PwVNsv9ov88vOAgoNiDa",
  "session": "{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"httpOnly\":true,\"path\":\"/\"},\"userId\":\"my-user-id\"}",
  "expires": ISODate("2016-07-09T08:47:38.156Z")
}

As you can see, session is a string, not an object, so you can't query it directly using session.userId.

If you can't use req.session.destroy(), you need to perform a regular expression query to match against the user id in the JSON string:

let collection = mongoose.connection.db.collection('sessions');
let query      = new RegExp(`"userId":"${userId}"`);
collection.remove({ session : query }, function(e, found) {
  console.log(found);
  res.json({success: true});
});

It's probably best if userId is first run through something like escape-string-regexp to make sure that any special characters are escaped properly.

Note that this isn't a fast query, especially if you have a lot of sessions in your database.

EDIT: I just found the stringify option for connect-mongo which, if set to false, should write the session data as a regular object to MongoDB, and not as a JSON string.

robertklep
  • 198,204
  • 35
  • 394
  • 381
  • You're assumptions are correct. I'm using `express-session` with `connect-mongo` to manage my sessions. On a `POST` to my logout API, I need to destroy these sessions. I have managed to do so by calling `req.session = null` inside my API and setting `unset: 'destroy'` in my session settings. Although, there is one small problem; my home page (`app.get('/',...)`) serves a different page if `req.session.userId` is not undefined. For some reason, I need to refresh my page twice after the logout API is called for it to be unset. – Fizzix Jun 25 '16 at 11:12
  • @Fizzix can you check in the database if the session belonging to the session key has been deleted after the request to the logout route? Or if perhaps `req.session.destroy()` works better? – robertklep Jun 25 '16 at 12:31