Transitioning from Mongoose-Auth to Passport for Authentication in Node.js

Up until about a week ago, I was using Mongoose-Auth, when I decided my app needed some cleaning up. For most simple Node.js apps, it makes sense to route everything through your app.js (or server.js, depending on your preference/framework) file. But once your app starts to get a bit more developed, it makes more sense to break some of the code out into separate files, not only to make it easier to read, but also to make it easier to debug.

In the process of trying to separate my code out, I started having issues with Mongoose-Auth. In particular, I had a really difficult time maintaining authorization (cookies) for a specific user from one page to another, and it wasn’t exactly clear how to pass authentication between files. So I decided to follow my friend’s advice and looked into Passport.

The beauty of Passport is that it’s a LOT easier to implement. It’s simple, and the documentation isn’t terrible. A bit of fair warning, however: if you’re relatively new to Node.js/JavaScript, then the documentation (which makes sense to those who are Node/JS ninjas) can be a bit confusing. So I recommend using the Passport Guide in conjunction with some solid examples, like this Locomotive-Passport Boilerplate and this login example.

But transitioning from Mongoose-Auth to Passport was a bit of a challenge. (Especially since I wanted to keep all the user data, passwords and all, intact in my MongoDB.)

Getting rid of all the Mongoose-Auth stuff was easy; just delete it all. And putting all the Passport stuff was also pretty easy; just follow the Passport Guide’s Configuration steps.

I did have to make a few modifications, though (thank goodness for MongooseJS!):

  1. Include the bcrypt module to salvage the hash/salt parameters in the user database, and create a virtual for the UserSchema to take the hash/salt information and transform it to/from a password.
  2. Create a verifyPassword method, to accommodate the bcrypt functionality.
  3. Define an authenticate static to handle the user authentication process for checking the user’s input information with what I’ve got in the database.

Perhaps the biggest issue I had, however, was in getting the app to recognize the session cookie generated by the user authentication. I was able to get to the login page, submit my login credentials, and verify that I existed in the database – but then I’d get rerouted to the login page, with the claim that I wasn’t authenticated.

It turns out that the express configuration has to be in a rather specific order. (No one informed me of this – so hopefully it’ll help someone else!) Specifically, the express.session variable needs to be configured before any of the passport variables are configured:

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.cookieParser());
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(require('stylus').middleware({ src: __dirname + '/public' }));
  app.use(express.session({ secret: 'applecake' }));
  app.use(passport.initialize());
  app.use(passport.session());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

Once that was done, however, I was free and clear! You can see all my code for CrowdNotes on GitHub. (Specifically, check out modules/user.js, accessDB.js, and app.js.)

Next stop: a more beautiful MVC layout for the app :-)