User Authentication with PassportJS

My next adventure in learning Node centers around mastering some of most common operations performed on web sites.  Recently I dove into user management and authentication.  The most common way that a web site secures it self is with a user name/password and then a cookie.  Web sites need to use this cookie because your authentication information needs to stay static between round trips to the server.  The web server needs to store who you are and the fact that you are logged in.  In recent years this story has change has you can now login with a facebook or google account to websites that are not facebook or google.  My intent with Node is to just get down the basics so I’m only focusing on a basic user name/password situation, but it would sure be nice if I could scale it out and swap out different login providers.  To handle user authentication I discovered the “PassportJS” middle ware that does just that.  Passport defines the core functionality and then relies on different “strategies” to swap out different providers.  In my experimentation I focused on the “local” strategy, but there are dozens of different strategies that connect to different login and authentication providers that you can use.  The local strategy is basically a do it yourself option, perfect for learning.  Getting Passport working required three things:
Define your authentication “Strategy”
Tell Passport how to serialize/deserialize users

Make sure you have the session enabled

My Strategy

To get going, I defined the implementation to my local strategy, which is simply to compare a login attempt to a hard coded list of user names/passwords.  It goes without saying that this is terrible practice, but I’m practicing.  A real life local strategy would call out to a database, hash the password and check for a match between user name and hashed passwords; oh, and not surface the user’s password out to the rest of the application.

Serialization

Second thing is to tell Passport how to serialize and deserialize user records.  When a user visits a page on your application, Passpost will hydrate the user record for you so that your application can have access to details about the user visiting the website.  In my example, that would mean that I could have access to the user’s name, password and id.  If this was a true local authentication, then I would be deserializing a user by executing a database call with a session identifier and pulling out a users information and then extending a session, certainly not leaking out a user’s password.

Remembering who you are

Unless you cache something off, the web server will forget every thing about your current request the next time you click on a link in the application.  I understood that in concept but the implementation in Node was lost to me.  Every blog post and example I read said that I only needed to define the above three functions and register them into Passport to have it start authenticating users.  However, every page load after that initial login was unauthenticated.  The secret that was missing was the Express Session.  Why was I missing that to begin with?  All the examples and blogs were out of date.  ExpressJS no longer bundles add ons, like session, in the core node package, they needed to be added and configured separately.  As soon as I added the “Express-Session” package and added a line to initialize it everything started working.  Cookies were set on the browser and user logins persisted across page loads.  My app started remembering who I was between pages views.

Automated builds with Travis

All developers should know the value in unit testing and automated builds.  They ensure quality is built and maintained in your software products.  You don’t want to have you interns come in and add some cool functionality into your product and deploy a broken product because they didn’t understand how their changes impacted existing functionality.  In my last post in this series I went over how to create unit tests for a node.js application.  Unit tests by themselves are great, but you (and your intern) need to execute them for there to be any value in having them.  Chances are that intern doesn’t know about unit testing and won’t know they should, or even how to, run the unit tests before committing their changes.  Fortunately there are tools that automate testing and reporting on commits.  Travis is one such tool, and it is free to use.  Setting it up for my node application was stupid easy.  There were three steps, first I needed to define a “default” gulp task like so:

 

gulp.task(‘default’, [‘run-tests’]);

 

This step is necessary because I only defined the “run-test” task in gulp when setting up the unit tests, Travis by default runs the “default” gulp task, so it needs to exist.  Second you need to create a “.travis.yml” file to define how Travis should run.
travis1
Third, you need to log in to Travis with your github account and select the repository to test.  That is it.  You are then running and testing automatically.  If all is setup up right you will see a screen like this shortly after pushing your changes to github, complete with your “build passing” badge.  Awesome!
travis2

Unit Testing JavaScript with Gulp and Mocha

Immediately after getting my first node project up and running, I started to ask how do I write and test my code?  My corporate experience has taught me the importance of automated testing, how to create them in C# with visual studio and how to automate the testing with TFS, but node and VS Code is totally different.  Visual Studio is an IDE and it will take care of almost everything for you.  You simply need to create a new project (a ‘test’ project) in you code and you are good to start writing tests.  Executing your test is as easy as a file menu click or a key board short cut.  You don’t have to think about the testing framework, how your code is built or executed because the IDE will take care of that for you.
Testing Framework
First question to answer was what does it take to write a unit test with JavaScript?  After asking around on Google I discovered node packages, mocha and should.  These libraries allow you to write simple and human readable tests.  In JavaScript, you don’t get classes per say, you need to think in terms of functions and prototypes.  In MS Test you typically create a test class that maps to one class in your code, the target class.  This thinking needs to evolve with JavaScript into files and functions.  One test file is used to test one file of code and you use functions, not classes, to define your tests.  With mocha there are two very interesting functions you need to know about, ‘describe’ and ‘it’.  When you see ‘describe’ think test class in MS Test.  Describe creates a container and label for your tests.  Now ‘it’ is the actual test, think a test method in MS Test.  The ‘it’ function needs a name and a function to execute.  The should package is what will help you make your tests more readable.  This package is similar to the NuGet package, Fluent Assertions.  It allows you replace robotic assert statements with more fluent and readable asserts.  In my experience of training interns, this fluent syntax goes a long way to help new people understand unit testing and understand what is actually going on in the tests.1
Testing Framework
First question to answer was what does it take to write a unit test with JavaScript?  After asking around on Google I discovered node packages, mocha and should.  These libraries allow you to write simple and human readable tests.  In JavaScript, you don’t get classes per say, you need to think in terms of functions and prototypes.  In MS Test you typically create a test class that maps to one class in your code, the target class.  This thinking needs to evolve with JavaScript into files and functions.  One test file is used to test one file of code and you use functions, not classes, to define your tests.  With mocha there are two very interesting functions you need to know about, ‘describe’ and ‘it’.  When you see ‘describe’ think test class in MS Test.  Describe creates a container and label for your tests.  Now ‘it’ is the actual test, think a test method in MS Test.  The ‘it’ function needs a name and a function to execute.  The should package is what will help you make your tests more readable.  This package is similar to the NuGet package, Fluent Assertions.  It allows you replace robotic assert statements with more fluent and readable asserts.  In my experience of training interns, this fluent syntax goes a long way to help new people understand unit testing and understand what is actually going on in the tests.
2 3
Once you have these in place you can run your tests with the test command in the command pallet or the keyboard shortcut.
4

Getting Started with Node

Recently I attended Microsoft’s Build conference in San Francisco.  Prior to the conference I had heard about Visual Studio Code and had starting fiddling around with it and MVC Core on Linux.  While I was there I had the opportunity to explore a few sessions and labs related to VS Code and Node.js.  Over my career I have learned many techniques for building quality into software products (such as: code reviews, unit testing, automated builds, etc.) and I have also accepted that when it comes to the user interface (i.e. JavaScript in my world) those practices either do not apply or are too time consuming to be worth pursuing.  As a result, I have formed a basised opinion and do not see any reason why a sane developer would ever choose to use JavaScript as a server side programming language.   And yet, they are and, Microsoft is promoted it.  What?  Why?  I have realized that I am missing something.  This blog series is documentation of how I’m exploring what I’m failing to understand, at the moment.
This first post will be very short because Microsoft has already done a good job of writing it 🙂  The first step in learning any new tool/framework/language is simply saying “hello” or more specifically, “hello world.”  Microsoft has provided an excellent tutorial for getting up and running with Node.

 

npm install -g express-generator
express ExpressApp
cd ExpressApp
npm install
You are then free to write in a hello world message…
image1
you can then fire up the debugger and point a browser to http://localhost:3000 to see the hello world
image2
From here I added in boot strap into the views and put together a nice starting point to branch out into future learnings.  You can see what I have done on my GitHub.