Welcome to Part 7 of this review of the Pluralsight course Building Web Applications with Node.js and Express 4.0 by Jonathan Mills.
Jonathan is a JavaScript and Node.js expert working mostly in the MEAN Stack with individuals and companies to help build their technical skills to cope with the constantly changing landscape of software development.
He is also an ASP.NET insider and an international speaker focusing on JavaScript both in the browser and on the server.
In this course we’re building a library application that’s going to keep track of a list of books. And in this module we learn how to create users, and do authentication and authorization using Passport.
Also in this series:
Part 1 – Getting Started
Part 2 – Setting up Express
Part 3 – Setting Up Gulp
Part 4 – Templating Engines
Part 5 – Routing
Part 6 – Databases
Sign in Form
In our index.ejs we create the Sign In and Sign Up Forms.
The sign up form has username and password inputs, and the submit button triggers the action at “/auth/signUp”
When we click the submit button it just takes us to a screen saying “Cannot POST /auth/signUp”
So we need to build the infrastructure to support this.
Creating the Auth Routes
In our Routes directory we create authRoutes.ejs
In here we have a router function with the route “/signUp”
We require in the bodyParser middleware.
This parses incoming request bodies in a middleware before our handlers. It used to be bundled as part of Express, and it is now a separate package.
Passport Middleware
A couple of pieces of Passport middleware we need to install and/or use:
- Passport.initialize() – to set itself up
- Passport.session() – place user onbject into the session
- Express session
npm install –save cookie-parser passport express-session
In app.js we write the app.use statements for these.
app.js is now looking pretty big and messy and separation of concerns says we shouldn’t have our authentication code here.
So we create config/passport.js
In our app.js we require in our new config/passport file.
Jonathan describes passport’s serializeUser and derserializeUser functions.
We use passport-local, meaning we’re just doing local authentication with a username and password.
npm install –save passport-local
Other authentication strategies are the OAuth providers:
- Passport Google
- Passport Facebook
- Passport Twitter
Jonathan has previously created the course “Securing Your Application with OAuth and Passport” so check that out if you need to.
Finally we create a new local.strategy.js file
Local Strategy
We map the names of our HTML inputs to our username and password in our LocalStrategy.
In this lesson we create a new route called profile and we send our user request information as JSON.
When we run it up, enter a username and password, and click the signup button, we get redirected to our profile page and see the entered userName and password information in a JSON object.
We also log this information to the console.
The next job is to create the user in our database.
Saving the User
Inside our post function we call mongodb.connect and save to our users object.
There are quite a few times in this course where Jonathan makes a mistake but carries on instead of editing that bit out.
Here we see the app blow up, and this is because our MongoDB database didn’t open. This is fixed by simply typing mongod into the command prompt and retrying.
We see superfluous data being returned in our results, so we change the code to only return results.ops[0]
User Sign in
We implement the sign in associated with our application, starting with the HTML.
We see an ugly sign in form with User Name, Password and Sign In buttons.
We use passport.authenticate with our local strategy, and an option argument telling it to redirect to the homepage on failure or to the profile page on success.
A useful article on this that I found is Understanding passport.js authentication flow
Verifying the User in the Database
We start by pulling in MongoClient.
Next we do the same thing we did in the previous module:
We invoke Mongodb.connect passing in our URL and a callback function which accesses our db.collection and gets a single result by using findOne.
We also see a simple way to deal with bad passwords. Initially we just redirect to a screen displaying “bad password”, and then we fix this to redirect to the homepage instead.
Securing Routes
We add some middleware to our profile route.
When we try to go to our auth profile we get
“TypeError: undefined is not a function” on the line req.redirect(‘/’)
This need to be res.redirect(‘/’) because will redirect off of the response, not the request.
Securing Multiple Routes
Instead of adding .all functions to each and every route, we can do this at the router level.
The final part – Structure and 3rd Party APIs is coming soon