How Do You Authenticate, Mate?
A definitive guide to authentication for software developers
We all know the common procedure for authenticating a user in our application. It’s the old-school method of registering a user with their basic info, such as email, password, etc..
Then, at the time of login, match the email and password with the previously stored data. If they match we give them access, otherwise we don’t.
But times have changed and a lot of other authentication methods have been introduced. To stay valuable as a developer in this fast-paced, ever-changing software development world, you need to know about these new methods.
It’s an undeniable fact that authentication is of the utmost importance in any type of application or system to keep the user’s data safe and have proper access to information.
To determine which authentication method is best for you requires knowledge of the authentication methods, their trade-offs, and mostly how they work.
I’ll try to introduce you to the most common and popular methods of authentication currently used.
It won’t be a detailed technical guide for these methods; more so an attempt to familiarize you with them.
Although the following topics are discussed with the ‘web’ in mind, the concepts aren’t limited to only the web. These concepts and methods can be useful in other domains too.
I’m assuming you already know that most of the Internet is built on the HTTP protocol. You should also already know how a web application works, what it means to authenticate a user to the application and what client-server architecture is.
Let’s get started.
The HTTP protocol is stateless. This means that, if we authenticate a user with a username and password, on the next request our application won’t know that this is the same person as the previous request.
We would have to authenticate again. At each request, HTTP doesn’t know anything about what happened before, it just carries the request.
So, for any request for private data, you would have to log in again to make sure the application knows this is really you. This would be very annoying.
To avoid this problem, session or cookie-based authentication was introduced.
It makes the authentication process stateful, meaning that an authentication record or session must be kept at both server and client-side.
The server needs to keep track of active sessions in a database or memory, while a cookie is created on the front end that holds a session identifier. This is why it’s called cookie-based authentication.
It is one of the most common and best-known methods of authentication that has been used for a long time.
Basic Flow of Session-Based Authentication
- In the browser, the user enters their username and password, and the request goes from the client application to the server.
- Server checks for the user, authenticates it and sends a unique token to the user’s client application. (It also saves this unique token in memory or database)
- The client application stores the token in cookies and sends it back with each subsequent request.
- The server receives every request that requires authentication and uses the token to authenticate the user and returns the requested data back to the client application.
- When someone logs out, the client application removes that token, so that subsequent requests to rails from the client become unauthorized.
A few major problems arise with this method of authentication:
- Every time a user is authenticated, the server will need to create a record somewhere on the server. This is usually done in memory and when there are many users authenticating, the overhead on the server increases.
- As sessions are stored in memory, this causes problems with scalability. If you replicate your server to multiple instances, you have to replicate all of the user sessions to all your servers, which complicates the scalability process. (Although it can be avoided by having a single dedicated server for session management but that is not always feasible and easy to implement.)
Token-based authentication has gained prevalence over the last few years due to the rise of single-page applications, web APIs, and the Internet of Things (IoT).
Tokens used for token-based authentication are mostly JSON Web Tokens (JWT). There are different implementations of tokens but JWT has become the de-facto standard.
Token-based authentication is stateless. We will not store any information about our user on the server or in a session, not even which JWTs have been issued to the clients.
Basic Flow of Token-Based Authentication
- User enters their login credentials.
- Server verifies the credentials and returns a signed token (the JWT) which can contain some additional information as metadata, such as user_id, permissions, etc.
- This token is stored client-side, most commonly in local storage, but it can be stored in session storage or a cookie as well.
- Subsequent requests to the server include this token, generally as an additional authorization header in the form of a Bearer, but it can additionally be sent in the body of a
POSTrequest, or even as a query parameter.
- The server decodes the JWT, and, if the token is valid, processes the request.
- Once a user logs out, the token is destroyed client-side, no interaction with the server is necessary.
If you want a more detailed explanation, try this article.
Benefits of This Method
The biggest advantage of this method is that it is completely stateless, the server doesn’t need to store any record of the user tokens/sessions.
Each token is self-contained, containing all the data required to check its validity, as well as convey user information through claims. That’s why it doesn’t add any complexity in scalability.
2. Store any type of metadata
With a cookie-based approach, you simply store the session ID in a cookie. JWT’s, on the other hand, allow you to store any type of metadata, as long as it’s valid JSON.
3. Single calls to database
When using cookie-based authentication, the back end has to do a lookup, whether that be a traditional SQL database or a NoSQL alternative, and the roundtrip is likely to take longer compared to decoding a token.
Additionally, as you can store additional data inside the JWT, such as the user’s permission level, you can save yourself additional lookup calls to get and process the requested data.
For example, say you had an API resource
/api/orders that retrieves the latest orders placed via your app, but only users with the role of admin have access to view this data.
In a cookie-based approach, once the request is made you’d have one call to the database to verify that the session is valid, another to get the user data and verify that the user has the role of admin, and finally a third call to get the data.
On the other hand, with a JWT approach, you can store the user role in the JWT, so once the request is made and the JWT verified, you can make a single call to the database to retrieve the orders.
4. Simpler to implement
While possible, there are many limitations and considerations for using cookies with mobile platforms.
Tokens, on the other hand, are much easier to implement on both iOS and Android. Tokens are also easier to implement for Internet-of-Things applications and services that do not have the concept of a cookie store.
Because of these benefits and the simplified approach, token-based authentication is on the rise.
The first reaction to the term passwordless authentication may be: “How could someone be authenticated without a password?”
This is because we’ve had it drilled into our heads that passwords are the ultimate source of protection for our account.
However, once you dig up some information about it, you might realize that, not only is passwordless authentication safe to use, it might be safer than a traditional username + password login.
You might also have heard some people say that passwords are obsolete.
What is Passwordless?
As you might have guessed already, passwordless authentication is a way to configure login and authenticate users without a password.
The general idea to implement a passwordless authentication is the following:
- Instead of a user giving an email/username and password, they enter only their email address.
- Your application sends them a one-time-use link to that email, which the user clicks on to be automatically logged in to your website or application.
- In the case of a passwordless login, the app assumes that you will get the login link from your inbox if the email provided is indeed yours.
There is a similar approach. Instead of sending a one-time-link to the email, it sends a code or one-time-password (OTP) through SMS. But you need to incorporate your application with an SMS service, such as Twilio, to make it work (it will also cost you money).
Also, it’s good to know that code, or one-time passwords, can be sent to email as well.
If you are using Slack, you might already have had a taste of passwordless login.
What Can Go Wrong With Passwordless
If someone has access to the user’s email account, they would have access to their account on your website or application too.
As developers, securing the user’s email account is not our responsibility; it is the user’s responsibility. Also, if someone gains access to someone’s email account, they could exploit their password-based authenticated applications using the ‘reset-password’ feature.
As this is the user’s responsibility, we will move on.
Benefits of Passwordless
Before answering that, I ask you to just think about how frequently you use ‘forgot password’ to reset your passwords. Also, the several failed attempts before that to login to a site or application because you couldn’t remember the password?
You aren’t the only one. It’s no wonder that remembering passwords is hard, especially if you are concerned with your account safety and set a different password for every site, following the at least ‘a number, a capital letter, a symbol, minimum 8 character length rule’.
Using passwordless authentication will save you from this headache. (I know, you might be thinking: “I use password manager, you idiot”. Respect to you. However, many users may not be as tech-savvy, you need to consider that.)
It is not only good for users, it’s good for developers too. Now, you don’t need to implement a ‘forgot password’, ‘reset password’ flow. This is a win-win for all.
If you really think that some of the users might still want to use the age-old email-password login, then you should give both of the options as Slack did, so the users could opt-in.
Needless to say, passwordless is becoming an increasingly relevant option for login and gaining popularity.
Single Sign-On (SSO)
Did you notice that, if you log in to any of the Google services, such as your Gmail account, from your browser, and then you go to YouTube or any other Google-based service, you don’t need to separately login?
You automagically gain access to all of the Google services. Fascinating, isn’t it? Although Gmail and YouTube are both products of Google, they are separate products, right?
So, how do they authenticate a user after single login to all of their products?
This method is known as single sign-on (SSO).
Single sign-on can be achieved in many ways. One way is to make use of a central service which orchestrates the single sign-on between multiple clients.
In the example of Google, this central service is Google Accounts. When a user first logs in, Google Accounts creates a cookie, which persists with the user as they navigate to other Google-owned services.
The process flow is as follows:
- The user accesses the first Google product.
- The user receives a Google Accounts-generated cookie.
- The user navigates to another Google product.
- The user is redirected again to Google Accounts.
- Google Accounts sees that the user already has an authentication-related cookie, so it redirects the user to the requested product.
Single sign-on (SSO) can be described very simply as “user logs in once and gains access to all systems without being prompted to log in again at each of them”.
This boils down to three different entities who trust each other directly and indirectly.
A user enters a password (or some other authentication method) to their identity provider (IDP) in order to gain access to a service provider (SP). User trusts IDP, SP trusts IDP, so SP can in-turn trust the user.
This seems so simple, but custom implementation of this would be very complicated. A detailed explanation of how SSO works can be found in this article.
I bet the following image is pretty familiar as you frequently see it in a lot of websites.
This is the thing famously known as ‘social sign-in’ or ‘social login’.
Using this, you can authenticate a user based on their social networking accounts. Users don’t need to register separately in your application.
Social sign-in, or social login, is not technically a different authentication method. Rather, it’s a form of single sign-on which simplifies the registration/login process of a user to your application and that’s why you should know about it (as a developer).
Social Login — Best of Both Worlds
First of all, for users, the login to your application is just one click away as they can use their existing social network account and don’t need to remember username or password. This results in a rich user experience.
Also, as a developer, you don’t need to worry about securing the user’s authentication credentials and you are ensured that the user’s email address is already verified (by the social service providers).
Another bonus point; the social provider will handle the password recovery process. Yay!
How Do I Add Social Login
As a developer, you need to know a little bit more about the underlying process. Most of the social providers use OAuth2 (some use OAuth1, e.g. Twitter) for authorization, as well as authentication mechanisms behind the scenes.
The key points to understand in OAuth are:
- The social provider is the ‘resource server’.
- Your application is the ‘client’.
- The user trying to login to your application is the ‘resource owner’ because the key ‘resource’ is the user’s profile/authentication information.
So, when the user wants to log in to your application, using the social provider, your application will redirect them to the social provider for authentication (generally a popup window opens with the social provider’s URL).
Along with the successful authentication, the user needs to approve your application’s permission to access the user’s profile information from the social provider.
Then, the social provider will redirect the user back to your application with some form of access token.
Next time, using that access token, your application can ask the social provider about the user’s profile information. This is how OAuth works in a nutshell (skipping some technical details for clarification).
To implement social login in your application, you might need to register your application in the social provider’s site, which will give you an
app_id and other related keys for configuration to communicate.
You will get this information in the respective social providers’ sites.
Two-Factor Authentication (2FA):
Two-factor authentication (2FA) strengthens access security by requiring two methods (also referred to as factors) to verify a user’s identity.
It is a type of multi-factor authentication which provides an extra layer of security.
You might not have realized it before, but when you go to an ATM booth or cash machine to withdraw money, you are being authenticated by a two-factor authentication system.
You must have the correct combination of the bank card (something you possess) and the PIN (something you know) to be authenticated. If someone steals your ATM card, it is of not much use until they also know your PIN.
That means, in a two-factor authentication system, a user is granted access only after successfully presenting several separate pieces of evidence to an authentication mechanism.
After enabling two-factor authentication in your account, every time you need to login to your account, first you provide the login credentials, such as email or password (verify that you know the credentials).
Then, a one-time password (OTP) is sent to you through SMS (verify that you possess the device), and you have to enter it correctly to complete your login process.
If your password has been compromised, your account is still safe, as the attacker cannot complete the second step without having the verification code.
Instead of OTP, another common method is to use the user’s biometric data, such as fingerprints or retina, as a second factor.
Two-factor authentication is based on the user providing two of the following three somethings:
- Something you know — the password or pin for an account.
- Something you have — a physical device, such as a mobile phone or a software application, that can generate one-time passwords.
- Something you are — a biologically unique feature to you, such as your fingerprints, voice, or retina.
Finding out the password or pin for an account is what most hackers are after.
Accessing a physical token generator or getting biological features is harder and the reason of why 2FA is effective in providing greater security for user accounts.
But, it will help you to strengthen the authentication security in your application.
Bonus Topic: Authentication vs Authorization
Some of us might mistakenly use the terms ‘authentication’ and ‘authorization’ interchangeably.
However, they are not the same thing:
- Authentication is the process of verifying who you are. When you log in to an application with a username and password, you are authenticating.
- Authorization is the process of verifying that you have access to something. That means the set of permissions you are allowed to. As an example, if you created a resource in an application you might be the only person allowed to remove it (as an owner), other users are not ‘authorized’ to remove this resource.
Congratulations, you’ve successfully completed reading this long, possibly tedious article.
Hopefully, you got a brief overview of the topics. If you find any mistakes or think any improvements are needed in this article, please leave a comment.