Understanding User Authentication in your Web App and how to implement it Part 1 (the high level overview).

Albert Kim
11 min readApr 26, 2019

--

Do not use this for your user authentication!

Stay tuned for part 2 where I walk through the steps to create a working full-stack web app with user authentication in React and Node…

What does it mean to have your web app be authenticated with a user’s credentials?

You could fake it with some JavaScript.

Just set up a prompt that accepts a user name and password, and no matter what, allow that user to go past the login screen.

That would technically count as implementing a UX flow for user authentication but you’d have to be a psycho to try and pass that off as real security.

For the more empathetic, implementing a proper and secure authentication system is a heavy task with real responsibility. If your web app does not have a secure authentication system you are potentially exposing your users to identity theft or fraud.

So how do you create an authentication system you can trust?

In this article I will attempt to explain what it means to have a secure authentication system in your web app and a high level overview of how to implement this system.

For this user authentication system, I will assume a few things.

- You’re creating a web app with a front end client (a browser like Chrome or Firefox).

- You have a separate server API that your client is interacting with.

- You want to use a user’s email and password to authenticate that user.

We will also be using cookies as the form of persistence for the login system.

Why a cookie? I could go into detail but that is not the important part of this post. If you really want to learn about cookies VS JWT you can watch this video https://www.youtube.com/watch?v=o9hT7v0OLJc

Why do you want to create a user authenticated application?

Think about the programs/applications you use most often. For me, it’s Youtube, email, social media, Reddit, and computer games (also programming related apps of course!). All of these applications are user authenticated and contains features specific to me.

Another reason for creating a user authenticated web app is to take your skills to the next level. I would create a lot of apps where anyone with a link could visit and view. I didn’t think anyone would use these applications so I stopped making them and focused on learning how to create user authenticated app.

Creating these types of apps is harder than creating an app that anyone can view and load up. Fortunately, after reading this post, you should have an understanding of the pieces required to implement a user authenticated system yourself.

The pieces involved in creating a user authenticated system

Cookies & Sessions

A cookie is a piece of data that is stored on each individual browser (the browser you’re using) that sends that data to the server that the web app is communicating with, on each request.

A session is a collection of data stored on a server (that is the back-end of the web app) that is associated with a user, usually via a cookie containing an id like the user’s id.

A cookie and session in action:

  • You go to www.webapp.com for the first time (you have an account somehow). At this point you don’t have a cookie set on your browser.
  • You login with your secure credentials.
  • The server (webapp.com’s backend) receives this login request, and accepts it.
  • The server then sets a session on your browser’s request containing your account’s user id.
  • The server then sends a cookie to your browser.
  • Whenever you go to webapp.com at this point on, your browser sends that cookie to the server. The server uses that cookie (which is the session on the server) and uses the user id set on the session to find your user account in the database.
  • The server finds a user, and returns your account information.

Database

If you’re reading this you should already know what a database is.

The role of a database in a user authentication system is used to store data about the user, such as their name, email, (hashed) password, and any other account settings like profile pictures or comments.

You check against the database to see if a user exists. This user entity is what your application uses to send data to the browser.

Server

The server is what receives all of the front-end’s requests and sends the browser data. This is an API of some sort, it could be RESTful or GraphQL or something else.

Basically, it is an application that (probably) lives in the cloud, and anyone visiting the front-end part of it (what you see when you visit www.webapp.com), can interface with this server through the front-end.

The front-end sends requests to the server and the server sends responses which contains data that the front-end uses.

Client

The client AKA the browser AKA the front-end.

This is the user-facing web app. This is what you see when you visit www.webapp.com. It could be a React.js app, it could be an Angular app, it could be a PHP app, it could be plain HTML/CSS/Javascript.

This is where you log in with a form or register with a form. The client then sends that form data to the server where the server checks the database to see if you should see sensitive data.

You interface with the server through the front-end.

For example, if you press a button that deletes an item in your inventory, the client sends that delete item request to the server, the server then receives that request and does the deletion action.

Registration and Login high-level overview

Now we are getting into the implementation details of user authentication.

The two essential functionalities of implementing user authentication are registering a user and then logging that user in.

Registration

A high-level overview of client and server interaction in registering a user.

There are a few different ways to implement registration. You can use an OAuth service with Passport.js with Facebook and Google accounts.

The one I am going to talk about is with email registration. This is where a user submits an email to create an account.

Here are the high-level steps to take to implement registration with email.

Step 1

Users send their email address and their password through a form to a registration request from the web app to the server. The code might look something like this:

Pseudo-code for registration with a form.

Why do you have to do this? Well if you are going to create a user object in your database that contains specific information about that user, then you need to identify them somehow. You do this with email. The user knows their email, so when they want to login, they enter their email, then you check if their email exists in the database.

You get the email and password from your front-end form, send that data through a request to the server, which then…

Steps 2/3

The server receives a request from your front-end (not just any front-end! #cors) that is a registration specific request and it contains the email and password.

The server then:

  • Validates the input
  • Checks the database to see if that user’s email exists in the database.
  • If it doesn’t then the server prepares to save that user by:
  • Hashing the password, saving the user, and then returning a response.

The code might look something like this:

Server registration pseudo-code.

Step 4

At this point, your user has sent a request from your website’s frontend to your website’s backend with a registration request containing their email and password.

If the registration is valid, then the server returns a response (the response could be a boolean, it could be an object, it could be null, it could be a string, it’s up to you). With this response, you should update your UI telling the user what happened.

Some developers also log their user in after the registration is successful.

Some developers will add an extra step of security for user accounts such as sending an email to the registered email to confirm they are the owner of the email.

You can research more about those steps on your own time. For now let’s move on to the login implementation.

Login

A high-level overview of logging a user in from the client to the server.

After your user registers and their user settings are saved in your database, they’ll be able to login to your web app to see their personal information.

This information could be the timeline of their friends posts if the app is Facebook. It could be a timeline of their followings’ tweets if the app is Twitter. It could be a feed of their followings’ pictures if the app’s Instagram.

If the user is not logged in and they visit your web app, they might see the default view for example with YouTube. If you’re not logged into YouTube and you visit their website, you’ll see the default videos that YouTube shows. If you are logged in then you’ll see a personalized home page of your subscriptions and recommendations.

Step 1

Your user is now on your website wanting to login. They enter their email and password in a login form that you prepared. It might look something like this:

Pseudo code for front-end login.

Steps 2/3

Once the user submits the login request from your front-end to your back-end, the login function is called on the back-end.

This function:

  • Validates the input
  • Checks the database to see if a user with that email exists
  • Then compares the password inputted and the password saved, and then sets a session with an identifier.

The code might look like this:

Pseudo-code for server login.

The line “ctx.req.session.userId = user.id” is the most important part of the login process.

Without this, the server won’t know which user is “logged in”.

When you make the call “ctx.req.session.userId = user.id”, what you are doing is creating a variable in your server that you can call to make dynamic calls to your database.

For example, to find a list of a logged in user’s friends, here is how you would use this session variable:

An example of using sessions.

You first check if the session is set.

If the session is set, then you find the logged in user by accessing their userId from when you made the “ctx.req.session.userId = user.id” call from the login function.

The server knows the current user id because when you set the user id on the session, the server sends a cookie to the browser containing that information.

When the user uses the same browser to visit your website, the browser automatically sends the cookie (set by the server) from the browser to the server on every request.

The server then takes that cookie, and matches it with the session set on the server, and then is able to retrieve the user id because the browser (with the cookie) sent that information to the server.

Without a cookie:

The browser makes a request to the server (no cookie set) -> Server gets that request and since there is no cookie sent with that request, there is no session to retrieve on the server and so there is no user id to look up in the database.

With a cookie:

The browser makes a request to the server (with a cookie) -> Server gets that request with the cookie containing the user id data, so the server is able to see the session with the user id set. The server is able to then look up that current user in the database by using the user id.

How do you set up the session on your server?

This part depends on your server. In my case, I use Node.js and Express.js to set up my servers. With these tools, setting up your app to use sessions might look something like this:

Session middleware for an Express app.

Basically, the server uses a session middleware which stores the session data using Redis (I won’t get into that here, but Redis is kind of like a light-weight performance based database. It’s used to store and retrieve values, like a database).

With this set up in your server initialization, you now have access to a session object in your server that is attached to the “request” variable. You access this session by using code like “ctx.req.session.userId”.

You are able to access the session like that because you added the session to your server in the middleware in your server config (the app.use(session()) part). If you don’t have that middleware config, then you aren’t able to access the session in your server code.

Stay tuned for part 2 where I will go over the steps to implement a working full stack web app with user authentication…

What’s next?

It’s time for you to try and implement a cookie/session based login system yourself! Practice and implementing things your own way is the best way to learn in my opinion.

You can read articles and do tutorials all day but when you actually build a custom system from scratch, that’s when your understanding goes to the next level.

Resources to take your skills to the next level

If you want to go through a course to have someone guide you through implementing a full stack web app with user authentication, here are some links to courses I recommend.

Ben Awad has great courses for free on YouTube and coding along with his videos is how I learned advanced full-stack web dev. Here is his channel: https://www.youtube.com/user/99baddawg/playlists

Another great instructor is Wes Bos. https://wesbos.com/

His courses cost money but they’re affordable and well worth it for the knowledge and project you end up with.

You can also read more about my favorite course instructors that helped me take my skills to the next level. I wrote a post about this very subject.

If you liked this post then feel free to show me love on Twitter!

I’m also a freelance web developer. Feel free to send me an email if you want to work together!

You can find my email on my website:

--

--

Albert Kim

Helping freelance writers build their business with a website builder designed for their needs at https://leavewithaweb.site