14

I am looking for a way to use the Twitter strategy for Passport.js without using a sessions collection/table in a database. The reason for this is we save all that data in the sessions collection which can get quite large and we save a database roundtrip whenever a user makes a request because we dont have to go to the DB each time to fetch the session data.

Anyway, we should be able to use a token (JSON Web Token) to authenticate a user, just how this great article describes:

https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens

But I am confused why there isn't an easy way to just do this with Passport? (The article does everything without Passport - but surely Passport has this covered?).

Perhaps I am overthinking this and the way to do that is just to omit the calls that I have in Express to use the DB session and then Passport is already smart enough to handle the the JWTs? Somehow I doubt that.

For example, surely it isn't enough to just comment out this code in my Express server:

//app.use(expressSession({
//    secret: 'arrete_x_paulette',
//    store: new MongoStore({mongooseConnection: mongoose.connection}),
//    saveUninitialized: true,
//    resave: true,
//    cookie: {
//        secure: false,
//        maxage: 6000000
//    },
//    proxy: false
//}));

and

//app.use(passport.session());

So what is enough, using Passport?

Why would anyone ever use sessions stored in the DB over using JWT based auth?

Alexander Mills
  • 90,741
  • 139
  • 482
  • 817

2 Answers2

5

Update: better solution is to disable sessions at all.

I think removing the session middleware for express and disabling it for passport by passing { session: false } to the passport.authenticate should work, see the docs.

The idea is that session data is stored inside the token, so you don't need the session at all. Storing it in memory (like described below) is only wastes memory. Storing it in cookies client-side also not good, because the client should decide where to store the token and not the server.


If you just want to keep express.js sessions in-memory and if you are using the standard expressjs's session to handle sessions, then all you need is to remove the store: new MongoStore(...) line:

app.use(expressSession({
    secret: 'arrete_x_paulette',
    saveUninitialized: true,
    resave: true,
    cookie: {
        secure: false,
        maxage: 6000000
    },
    proxy: false
}));

By default it uses MemoryStore, see the documentation.

Borys Serebrov
  • 15,636
  • 2
  • 38
  • 54
  • yes thanks, actually using cookieSession is better than expressSession, because it seems to maintain the session even if the server restarts. – Alexander Mills Jan 23 '16 at 01:45
  • @AlexMills I think with cookieSession it looks weird - it stores the server session on the client, but in the case of JWT the client should decide where to store the token by itself. This way you can end up with double token stored on the client. On the second thought the better solution is to just remove `expressSession` middleware at all as you suggested in your question. Did you try it? What was the problem with this solution? – Borys Serebrov Jan 23 '16 at 07:52
  • @AlexMills probably what you need to do is to [disable passport.js sessions](http://passportjs.org/docs#disable-sessions) too. There is no neeed to store anything on the server since session data is inside the token. – Borys Serebrov Jan 23 '16 at 08:02
  • @AlexMills also found an [app example](https://github.com/RelativeMedia/express-api-boilerplate) which seems to use the approach with no sessions at all, maybe it can be useful to you. – Borys Serebrov Jan 23 '16 at 08:22
3

@Boris Serebrov answer is mostly correct. You probably want to set {session: false} so that sessions aren't stored in memory on the server itself, along with not saving sessions in a database. But there is probably a little more to the story.

One of the reasons why people use a persistent memory store is because this means that if a server restarts, the sessions don't get lost. However, we have been promised stateless JWT token based auth. So if it's stateless, why would it matter if the server restarts? As soon as the server is back up and running, the same token should be valid, no matter the state of the server, right?

I have found, in my brief foray into this, that expressSession will provide sessions that will be lost if the server restarts. This probably motivated people to use persistent sessions using Mongo and Redis, in the first place! But you don't need to do that! I don't see any reason to use persistent sessions stored in DB. You should be using JWTs and stateless auth...so the alternative seems to be cookieSession, another module for Express.

If you use cookieSession like so:

app.use(cookieSession({
    name: 'some-cookie',
    keys: ['key1', 'key2']
}));

then even if you server restarts, the 'session' remains. This works with your current Passport configuration, as long as you remove the call to store sessions in MongoStore, etc.

https://github.com/expressjs/cookie-session

Please correct me if I am wrong or overlooking something.

Alexander Mills
  • 90,741
  • 139
  • 482
  • 817