User Authentication With Passport.js

Change Log

1. November 21st, 2013: After a user registers, they are automatically logged in

In this post I’ll demonstrate how to add user authentication to Node.js with Passport.js.

If you’re interested in social authentication, please check out this blog post.

Contents

1. Setup
2. Edit app.js
3. Mongoose
5. Test
9. Test redux
10. Unit tests
11. Error handling
12. Conclusion

Setup

Start MongoDB

In a new terminal window, start the MongoDB daemon:

Test locally

Navigate to http://localhost:1337/

Mongoose

Let’s get the database going …

Add a new file called “account.js” to a new directory called “models” with the following code:

You may be wondering about password security, specifically salting/hashing the password. Fortunately, the passport-local-mongoose package automatically takes care of salting and hashing the password. More on this further down.

Test

Fire up the server. Make sure you do not get any errors. You should PUSH to git and/or Github now.

Test redux

Fire up the server and test! Register, then login. PUSH to git again.

Remember how I said that we’d look at salting and hashing a password again? Well, let’s check our Mongo database to ensure that it’s working.

When I tested the user registration, I used “Michael” for both my username and password.

Let’s see what this looks like in the database:

So, you can see that we have a document with five keys:

• Username is as we expected.
• _id pertains to the unique id associated with that document.
• __v is the version # for that specific documents.
• Finally, instead of a password key we have both a salt and a hash key. For more on how these are generated, please refer to the passport-local-mongoose documentation.

Unit tests

Add a Makefile to the root and include the following code:

Take note of the spacing on the second line. This must be a tab or you will see an error.

Error handling

Right now we have some poorly handled errors that are confusing for the end user. For example, try to register a name that already exists, or login with a username that doesn’t exist. This can and should be handled better.

Registration

First, update the /register route so an error is thrown, which gets sent to jade template, if a user tries to register a username that already exists:

Then add the following code to the bottom of the “register.jade” template:

Next, if you try to login with a username and password combo that does not exist, the user is redirected to a page with just the word “Unauthorized” on it. This is confusing and unhelpful. See if you can fix this on your own. Cheers!

Conclusion

Simple, right? Grab the final code here.