Using Passport for Node.js Authentication

Yesterday I build an application that used express to serve up JSON objects as a route as well as full-populated template html files, connected to mlab as mongodb instance. Functionality was limited to create and reads, and hosted on heroku.

This application will build upon that knowledge for full CRUD functionality as well as building in user logins and authentication using passport module. This is the traditional model of user authentication for an application, and a good place to start, but there are lots of other strategies including using an OAuth partner like Facebook to login. That might be something I explore a little later down the road :)

Passport is middleware software for Node.js which offers a wide spectrum of authentication possibilities, more than 500 actually!- you can read about them here.
But, at its core, Passport is just about authentication.

Passport uses authenticate method to select the strategy, (which needs to be configured before being invoked), and can have redirects and flash messages.

 

Refactoring Local Mongodb Instance to Cloud

I came across a frustrating “learning moment” as the express app that I’d built, which worked fine on my local MongoDB instance, refused to work correctly when striving to use mLab’s cloud service.

I first started with swapping out the ‘localhost’ URI with the connection URI that mlab provides, yet the driver would not recognize the collection which I had instantiated within the database.

After reviewing a variety of posts and the MongoDB documentation, the connection worked correctly when I added:

1
2
3
4
MongoClient.connect(url, function(err,client){

if (err) return console.log(err)
db = client.db('personal_library')

Express Sessions

I’m enrolled in the MongoDB University M101JS class, already entering week 4!, and it’s been a deep dive in CRUD. I’ve been taking lots of notes, but for me the best thing to make sure it sticks is to put what I’m learning into practice. So, I’m working on tying in a MongoDB instance to node.js + express. I’m going to share what I learn as I go along.

Assuming that the goal is to build an app so that a user can log in via authentication, and then query data saved in the database, building in sessions will be important so that there is state in terms of that user’s experience.

Installing the express-session module, we then use it as middleware and setting a configuration object to it. There are four fields, with the keys of ‘secret’, ‘resave’, ‘saveUninitiated’, and ‘cookie’. With sessions initiated, and these parameters set, we then have access to the session object attached to the request body as a parameter. We can access that session object with subsequent requests.

For example, if I set the session using those four key values, I can then access request.sesesion with subsequent routes (which have the request and response parameters as part of the callback function).

In the example that I’m working right now, I successfully created a simple value attached to that session object, which was sent to the client as part of the response, and was still available with subsequent user/client requests. So, I’ve gotten a glimpse of what this can mean.

It’s important to note that there are four different ways of working with sessions: in memory (which isn’t used for production), in a cookie (which is what we have used here), in a memory cache (like Redis or Memcached), or a database. In one of the blog posts I read, it was recommended to approach sessions using caches first, then cookies, and finally databases.

However, the disadvantages of using cookies is that it adds to the overhead of a http request or response, with that added data being carried each way. The amount of data is relatively small, but it still adds overhead. Also, it’s essential to keep the cookie secret just that - a secret, because if exposed, then the client’s data is as well.

AWS Certified Solutions Architect - passed

Today I successfully passed the AWS Certified Solutions Architect exam - it was a quite difficult exam to take!

This is a description of what the test entailed:

The AWS Certified Solutions Architect – Associate exam is intended for individuals with experience designing distributed applications and systems on the AWS platform.

 

Criteria

This was the second time that I took the test - the first time was back in January of this year. That time, I’d focused mostly on studying the whitepapers (technical documents that Amazon provides), and reading books - in short, mostly striving to understand it from a theoretical perspective. What I quickly learned, however, is that the test is focused pretty heavily on scenario-based questions, and in my opinion that can only really come from getting your hands dirty and really understanding the AWS cloud concepts and services very intimately through hands-on practice.

So this time, I went through the course taught by ‘A Cloud Guru’, took notes, and spent a lot of time actually putting what I learned into practice. I built EC2 instances, and then killed them off. I built Ubuntu and Linux servers, Windows instances, spun up S3 buckets, replicated them, linked them to EC2 instances, and put them all behind load-balancers and within a local networked instance - a VPC. I learned to SSH into my instances, configure them, and gradually became comfortable with understanding not only the power of all that AWS cloud services provide, but with working with them. As a developer, I find it really interesting in being able to leverage the power of Amazon’s infrastructure for amazing new possibilities!

AWS EC2 instance using SSH Blink and nginx reverse proxy server

 

There’s my fancy splash page! I wanted to share the steps I took to get some experience doing a few things: first, creating an EC2 instance within a VPC, then spinning up a simple express app on top of node, spitting out response to port 3000 but allowing our reverse proxy nginx server to channel that to route 80.

First step was that I started with the VPC that I created in yesterday’s post. Basically, I created a VPC with a 10.0.0.0/16 CIDR IP address block, and then I created four subnets within the VPC - one is for expansion uses, and the other three each were situated within a different Availability Zone. Why did I do that? For fault tolerance reasons, as we can locate a server within a different subnet, in the case an AZ goes down, another mirrored server can be spun up. Also, it made it easier to allocate the CIDR sub IP ranges.

I went ahead and deleted the EC2 instance that I’d spun up yesterday, and created a new one using a Linux AMI, without additional storage, using a security group which allowed SSH, HTTP and HTTPS. I created that EC2 instance within the us-west-2a availability zone.

Next up, I created an Internet Gateway which I associated with the VPC. I actually didn’t need to do that, as I’d done that yesterday, but just wanted to get more practice :)

Next, I created a route table that was attached to that Internet Gateway, and which had two routes pointing to the IG: the first was for HTTP and the second was for HTTPS. Each subnet needs to be attached to a route table. So, for the subnet that was located within us-west-2a availability zone, I had the (soon to be provisioned) EC2 instance pointing to the route table which was publicly facing via the IG.

Okay, so that’s good. Now that we had that infrastructure, we could spin up the EC2 instance. Nothing fancy, just a Linux instance using free tier AMI, and plugged it into our subnet within our VPC.

Building the EC Instance

  1. SSHd into the instance using the key-value pair
  2. wihtin the trusted keys subfolder, added the public key from Blink
    Boom Now am connected by Blink and my laptop at the same time oh yeah!

  3. installed nvm

    1
    curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash

then installed node:

1
# nvm intall node

then:

  1. made a directory
  2. cd’d into that directory
  3. $ npmm init
  4. npm i –save-dev express
  5. created server.js file with verrrrrry basic exepress server, listening at port 3000
  6. installed nginx

    1
    sudo yum install nginx
  7. edited the nginx config file to point to server behind it with port 3000
    link

  8. restarted ngnix server

 

Creating a VPC With a Single Public-Facing EC2 Instance

I wanted to share how I successfully created an EC2 instance within a VPC instance, using a custom route table and connected to an internet gateway. I find working with the cloud to be super interesting, but there’s a lot of moving parts, and I thought it’d be helpful to share this successful step with other interested parties.

So the goal was multifold: to create a VPC, a NACL, a route table, an internet gateway, a subnet, and a security group. Also, to spin up an EC2 instance within one of two subnets, the one which is public facing and internet accessible.

Here’s the result of this blog’s efforts:
 

The first thing that needs to be done is to create a VPC. Now, I’m assuming that you already have a AWS free-tier account that you can access. Within the VPC Services, you can create a VPC by using a descriptive name tag, and selecting an IPv4 CIDR block.

The IPv4 CIDR block is basically an IP range that you’ll have available to you within your VPC. So what’s a VPC? It’s like your own virtual private cloud, your own data center. So what we’re working on is configuring the network within our own little VPC world :) Just to have more options, I also selected Amazon providing a IPv6 CIDR block as well. And that’s it for creating a VPC! Amazon does some behind-the-scenes work, by creating a default route table, network ACL, and security group as defaults.

Here’s what we have so far: a VPC structure, and a few defaults: route table, NACL, security group. Right now the route table, by default, is open to the whole wide world, something that we don’t necessarily want and will be fixing next:
 

Next up, we need to create a subnet, which is a logically-distinct area of your VPC. You can have multiple subnets, and they are each their own little kingdom (is how I like to think of it). They can interact with each other using peer sharing, but it’s all very controlled. Which is complicated, but super powerful!

Anyways, let’s create our subnet! Still within the VPC service category, we do so by selecting a distinctive name, selecting the VPC that we just made, and then selecting a CIDR range (yes, again). Before, we selected 10.0.0.0/16 because that gave the widest range of IP addresses, but now we don’t need so many, so we can just select 10.0.1.0/24. Each subnet is associated with a unique Availability Zone (AZ), so you select the AZ that you want this subnet to be in. And, that’s all you need to do to create a subnet.

For this exercise, I haven’t linked up my subnet with another, I’m just going to focus on getting the single EC2 instance, subnet, route table, NACL, and internet gateway working. Baby steps! :)

Now, we need to think about the internet gateway, because we want to our soon-to-be-provisioned EC2 instance to be able to access the internet. So, once again within the VPC services category, we can create an internet gateway (IG), by simply creating it (give it a name if you like), and attaching it to our VPC.

So, now we have this:
 

Next, we have to create our route table, and that’s because the default one which AWS configured for us automatically when we created the VPC, is set, by default, to the internet. That’s not a problem, but also by default, all subnets are attached to that route table, and we don’t want all of our subnets to necessarily to be exposed like that. So, let’s create a route table that’s especially tailored for public access.

We can do that by creating a route table and creating two new routes as part of that table (From the Route Tables selection, just go ahead and select the route table that you just created. Now, at the bottom you should see a tab called Routes, and there you can add those two routes).

The first route we want the destination to be ‘0.0.0/0/0’ for HTTP access and attach that to the internet gateway. The second raoute we weant to be ‘::/0’ which is used by the HTTPS. Now, what we have done is create a route table that is pointing to the internet gateway and that has approved two routes for HTTP and HTTPS access. Cool! The last thing that we need to do is actually associate that route table with our subnet; you can do that by selecting the subnet associations tab, select the subnet that we’ve been working on, and they are now associated.

Oh, wait, there’s one more thing that we have to do! We have to allow AWS to provide public IP addresses, which we need for accessing the internet. We can do that by selecting VPC > Subnets and then selecting our VPC. Now, select ‘Actions’ > ‘Modify auto-assign IP settings’ to true.

Now that we’ve created the framework architecture, we can go ahead and provision our EC2 instance. I selected the Linux free-tier 64 bit AMI, on a micro t2 instance, selected the VPC and subnet that we just created, and also selected a security group (firewall) that allowed SSH, HTTP, and HTTPS into that instance. And with that, we can SSH into our instance.

One fun thing to do is add a shebang bash script to our EC2 instance:
yum install httpd -y
yum update -y
chkconfig httpd on
service httpd start
echo “

hello world

“ > /var/www/html/index.html

That script goes in the advanced settings of the EC2 instance setup. If you do that, then the instance will spin up, update its settings, install Apache server, start it, make sure that it boots up upon server rebooting, and create an index.html file that is served by the Apache server. You can access that via the public DNS address that is given in your EC2 instance page.

And with that, we have successfully completed what we wanted to do!
 

AWS EC2 Instance Using ELB and Simple Route

Lately I’ve been exploring moving my MERN applications up into the cloud using the AWS platform, and I thought I’d share how I configured setting up an EC2 instance using an Elastic Load Balancer. Hopefully it’s useful!

First, I set up two generic EC2 instances within my local Region (Oregon, or us-west-2), using an AWS Linux AMI, a bash script to first install updates, then spin up Apache server, make sure that that server always rebooted, and then creating a simple html file within the server’s /var/www/html folder. So, at this point, there are two EC2 instances running.

Next, I created an Elastic Load Balancer in front of those two EC2 instances. For that, I used the default HTTP port 80, used the same security group as what i’d used for the EC2 instances, dialed down the health check timing parameters to more manageable time slots, with the health check pinging the index.html file that had been spun up.

Et Voila! To test this out, I first went to my EC2 instanes, grabbed the IPv4 public addresses and opened them in my broweser - good, they displayed those html pages correctly. Then, I copied the ELB public address and put that in my browser and that worked too.

The next thing that I learned was about DNS and Routes. That’s always been somewhat mysterious to me! But here’s a summary and overview of DNS, and then I’ll build on that to how I used that info.

DNS

So, DNS converts human-friendly URLs to an IP address - you know, those ones like http://126.10.12.10? Yes, impossible to remember! We have IPv4 IP addresses, which are 32 bit ones, but with the explosion of IoT and such, we’re running out of those, so there’s a new sheriff in town, the IPv6, which is 128 bits, and TONS of IP addresses!

Then we have Top Level Domains, which are the .com, the .net, sort of deals. There is a database that tracks all available top level domains.

That’s where the Domain Registrars come into play- they assign domain names within each of those top-level domains. That’s what GoDaddy.com and such do.

Now, when you register a domain name (and I’ll use AWS’s Route53 as an example), then you’ll be given SOA and NS records. What the heck are those? Well, you need both of those, at a minimu. The SOA records point to the server which originated the domain name, and will tell you who owns the domain for example. The NS records, on the other hand, are used by the Top Level Domain servers to direct traffic to the DNS server. So zerr important! Lastly, you need an A record to map the name to the IP address.

Back to the example

With that as a backdrop, I’m now going to create a simple A route. I used the naked domain name, or the apex domain, which basically means without the ‘www’, and pointed it to the ELB IP. What that does, basically, is that this route will route the request to the ELB, which sits in front of the two EC2 previously located, and those EC2 content will be displayed.

AWS has a lot of resources to offer, as I learn this ecosystem I’ll continue to share what I’ve learned in case it’s helpful to someone else :)

Updating Content-Type in Uploaded S3 HTML File

Using the AWS docs, I was able to successfully upload an html document to my s3 bucket, but when I attempted to open that file from the bucket, it would only download the uploaded file. Not what I wanted - I was expected to view the page in the browser.

What I learned is that the default that AWS sets for uploaded files (and I believe that’s across the board) is of the MIME type ‘application/octet-stream’. In order to set the correct Content-Type of ‘text/html’, list of MIME types, I added the ContentType property as the key within the AWS params, like so:

var params = {
Bucket: ‘‘,
Body : fs.createReadStream(file),
Key : path.basename(file),
ContentType:’text/html’
};

Those params are used within the s3.upload method, and with that change, the file opens correctly.

Node.js and the Event Loop

I’ve been diving into better understanding node.js, the Javascript runtime that runs on the server, and thought I’d post some of what I’ve discovered.

Mozilla has an excellent article on the concurrency model and event loop. I first googled that article by seeking to understand the difference between a process and a thread; node.js is a single-threaded runtime, but in actuality it’s only single-threaded in terms of what the user can access. That is, node.js uses the open-source libuv library to handle the thread pool, and that libuv allows for concurrently running javascript code to be running at the same time as the main (user facing) single thread. Another thing that I learned is that a process differs from a thread in that the former uses different memory locations, while the thread using a localized memory area. At least, I think I got that right :)

So the single thread is possible because node.js is non-blocking, that is, using asynchronousity. This is possible due to the event loop, which is comprised of a stack, heap, and queue. From my understanding, which is pretty simple at this point, the heap is just Max Beyond Thunderdome memory area where arrays and variables are put in an unstructured way, the stack is where functions ‘put’ (no pun intended) as they are called, and the message queue (or event queue or task queue, whichever you prefer) is where messages (which are attached to functions) wait patiently for their turn. When it is their turn, i.e. some event has returned, then they are called, and that means that they are put onto the stack, because that’s where functions go when they are called. The stack ebbs and flows, as functions are called and returned, and node will keep on chugging along through the event loops so long as there is code being run or there is a messsage in the queue.

Whew! It’s actually pretty interesting, but I can tell this will take some time to really wrap my brain completely around!

A Few Webpack Insights

Webpack has always been a little mysterious for me, which is why I’ve tended to fall back to Create-React-App. A couple of insights that I received today that I wanted to pass along:

1
2
3
4
5
6
7
"scripts": {
"start": "node src/server/index.js",
"build": "webpack --mode production",
"client": "webpack-dev-server --mode development --devtool inline-source-map --hot",
"server": "nodemon src/server/index.js",
"dev": "concurrently \"npm run server\" \"npm run client\""
}

This was the scripts that I built into my package.json for a back-end express server and a front-end react rendering. What I want to point out are these (for me) interesting insights that helped take away the mysteriousness of webpack machinations:

  • the ‘start’ script will be used by the app after production has been invoked, and that’s because all the html, css, and js files will have been bundled by webpack into a file called ‘bundle.js’ which is sitting in a folder called “dist”.
  • the ‘build’ script uses a mode that webpack offers, and it has to do optimizations. For production, it offers these:
1
Provides process.env.NODE_ENV with value production. Enables FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin and UglifyJsPlugin.
  • the ‘client’ script spins up webpack-dev-server which does what nodemon does, refreshing browser changes instead of back-end server. Once again we have that mode for optimizations, we have a source map which is good for development and we’ve set it for hot reloading

  • the ‘server’ script is for spinning up the express server

  • finally, ‘dev’ script allows us to access the html, css, js files without webpack bundling them

Anyways, diving into studying these parts of webpack were helpful for me!