Koa Authentication with Enmap
In this example we'll be using Enmap to store user data in order to authenticate users on a simple Koa application. In order to make this secure, we'll be using bcrypt
to encrypt the passwords, so of course they will not be plain text in the database.
Requirements
We'll be using koa
as a web server module, along with koa-session
in order to store the session information. Additionally, for ease of use, koa-router
is used to simplify the route code.
This tutorial uses
koa-session
which, by default, is insecure since it stores the entire session data in a browser cookie. This means the password, though encrypted, would be availble in the cookie, and easy to spoof. There are many session stores available for different storage system, but using them is beyond the scope of this example.
To install those requirements, run the following in a new, empty folder for your project:
Once all of those are installed, we're ready to start! We're going to create an index page, login page, and one "protected" page that requires login. Let's start with the top of the file, which is all the required modules:
So now we have all the basics necessary.
Account Creation Function
Let's create a few functions specifically for the login features, related to enmap. First, a function to create a new user:
This function takes in the following arguments:
username
which obviously is self-explanatory: it's the username entered during login.name
is the "full name" or "display name", for a friendly display on the page or an email.plainpw
is the password desired for this account. It has to come in as plain text, obviously, in order to be properly saved in the database.admin
is a boolean value representing whether the user should be administrator. If creating something like a blog, only an administrator could create other administrators. It's false by default.
The function first checks if the username exists and returns an error if it does. It then generates a salted, hashed version of the password which it stores in the database. Don't let the name fool you, the password is not "encrypted", which implies that it can be decrypted. Instead, it's a "cryptographic hash functions", a unidirectional function that cannot be undone. The only way to verify that a password is correct is to re-hash it again and compared the hashes.
Once the hashed password is obtained, the user itself is stored in the database with all 4 incoming arguments except the password which is the hashed version.
Login Function
The login function takes in the username and the incoming plain password and verifies that the hashed version corresponds with the one stored in the database.
An important point here is that this function returns a promise in all cases. If the username doesn't exist or the password is blank, a false
response is returned in a promise. Otherwise, the response of bcrypt's compare
function is returned. This function returns true if the passwords match, false if they do not.
Defining some app settings
There's a few configuration items we need to take care of. First off, the session settings:
Then we need to setup how Koa will handle rendering EJS pages. This is one pretty awesome thing about Koa, that this can be setup automatically and globally, but don't let me gush all over this!
Basic Routes
So let's establish our "routes", which is the pages that can be accessed by the browser. With the help of the Router, this can be really straightforward.
Then we have the login route, which does a lot of the bulk of our work. It checks for login, and adds everything it needs to the session in Koa if the authentication is successful:
Let's also create a logout function, that simply destroys the current session and returns the user to the index:
This one is pretty straightforward, so I don't think I need to get into the details, right? ;)
Lastly, we have the route for our "private" page. the one that only works if you're logged in. Now, there are "better" ways to establish protected routes, but let's go with the simplest one for now. We're just going to check for the logged
property of the session to determine if the user is logged in.
The End of the File
At the very end of our file we still have a bit of stuff to add. Mainly starting the server, but also telling the parser and routers to initialize. This would be how it's done:
Creating Templates
While templating is slightly beyond the scope of an authentication tutorial, I would be remiss to ignore the fact that logging in without a page would be... let's say a little hard.
Koa's EJS templating configuration, that we did above, means that templates need to appear in the views
folder. There will be a few template files:
template.html
will be the "main" template. It will have the header, footer, and whatever else we want to appear on every page.index.html
will be the main page everyone can access.login.html
contains the login page and formsecret.html
has a little secret about something.
Let's start with the template.html
file.
The <%- body %>
tag is where the contents of the other pages appear.
The index.html
is just some welcome thingy that we aren't concerned about:
Then we have the login.html
page which has our form. The form simply posts back to itself, so it'll trigger the .post
endpoint:
And, finally, the secret.html
page we've all been waiting for. Nothing that you haven't heard before, though:
With all said and done, This should be your project. Want a more "advanced" version of this project? Check out My full blogging platform, Koarrots.
Last updated