© 2024 Kishan Kumar. All rights reserved.

How Authentication Works: A Step-by-Step Explanation of the Process Behind Signing Up and Logging In

I recently wanted to build a project where I was required to have a feature to authenticate users.

Sept 05, 2023


Photo by Google DeepMind on Unsplash

I recently wanted to build a project where I was required to have a feature to authenticate users. I was presented with multiple options; I could use Google Sign In, for example, and some libraries to get this thing done. But that wouldn't quench my thirst for understanding what is happening behind the hood.

So, I decided to implement a login flow myself. I asked myself, how do I implement this? How do I verify that the user who is connecting to the server is a valid user?

We can have a simple sign-up flow to define who is valid or not. We'll start with the case where the user is not registered but wants to access our server features; one feature could be to get cute dog videos. I love dogs.

Mr. Fluffy

Here is what we want from the user:

  1. We take the email and password of the user using some form.
  2. We then save it to a DB, and once saved, we return a greeting that you have successfully signed in.

But the next time they send us the request to get the dog videos, we'll be confused if this request came from them.

For simplicity, let the email be alex@example.com and a super strong password that even quantum computers cannot break: 123.

For a moment, assume you are a server; you serve dog videos to whoever can prove that they have already registered with you.

Let's say Alex sent you a request:

1GET /videos/dogs

As a server, all you would see is a simple GET Request: It doesn't have any identity attached to it. Bob can also send the same request:

1GET /videos/dogs

But Bob is not registered. As a server, you have to send the videos to Alex but not Bob. Even though Alex has registered himself, his and Bob's requests are identical. What can we do?

Why not pass the credentials along with the request?

Hmm, I hear you, but how? In headers?

That could be one solution, but do you know anybody can intercept your request, and once they do, they can get hold of your credentials? And who knows how many places you have used that same quantum-safe password?

Why not encrypt the credentials, then?

Are you saying you'll encrypt the credentials from your side? And how the hell will the server know how to decrypt it?

Well, I can send the key to decrypt in headers. But if we do that, we are again back to square one; anybody can intercept and decrypt the key.

Come on, think, think!

Why does the client need to do any of the above things? That'll be super complex, and nobody will like watching the dog videos from your website.

Since we are engineers, we have to think of a way.

Let me think out loud: When the user signs up the first time, the server will generate an encrypted token using our credentials (that, as a client, we need not be aware of). The server will then save that token in our Cookie.

Gibe me Coomkies, Dammit

Gibe me Coomkies, dammit.

Cookies are small pieces of text sent to your browser by a website you visit. They help that website remember information about your visit, which can both make it easier to visit the site again and make the site more useful to you.

The thing with cookies is they will be sent automatically to the server whenever you make a GET request for a dog video on the website.

This time, when you sent a request to watch a dog video, the server received two things:

  1. GET /videos/dogs
  2. Cookies (associated with your website).

Now, the server takes the Cookie and eats it, and when it is done eating it, it sends you the videos.

Just kidding, since it was the server that encrypted it, it knows the key to decrypt it as well; it decrypts it and gets the information: {email: alex@example.com, password: 123 }. It then matches it with the DB, and once it verifies that, it happily sends you the videos.

Everyone is happy; you got your dog video, and the server got his cookies.

But how do I implement it? This I will elaborate on in my next post.

PS: This is an overly simplified article on how the login flow works. I have deliberately left a few things, such as:

  • The article assumes that the server will store the user’s password in plain text, which is a very bad practice. Passwords should be hashed and salted before storing them in the database so that even if the database is compromised, the attacker cannot easily recover the original passwords. (Please read the reference if interested)
  • The article also assumes that the server will generate an encrypted token using the user’s credentials and store it in a cookie. This is not how most web applications implement authentication. A more common approach is to use JSON Web Tokens (JWTs), which are self-contained tokens that include a payload with information about the user and a signature that verifies the token’s integrity. The server does not need to encrypt or decrypt the token, nor does it need to store it in a database. The token can be stored in a cookie or in the browser’s local storage, and it can be sent to the server with every request. The server can then validate the token and extract the user’s information from the payload.
  • The article does not talk about expiration or revocation of tokens. Tokens should have a limited lifespan and should be refreshed periodically to prevent them from being stolen or reused by attackers. Tokens should also be revoked when the user logs out or changes their password, so that they cannot be used to access the application anymore.

Thank you for reading this article. If you like this article, please show your support by subscribing to my newsletter or commenting.

.   .   .

The 0xkishan Newsletter

Subscribe to the newsletter to learn more about the decentralized web, AI and technology.

© 2024 Kishan Kumar. All rights reserved.