7 Authentication Concepts Every Developer Should Know
By Hayk Simonyan
Summary
Topics Covered
- JWT Enables Stateless Authentication
- OAuth 2 Is Authorization, Not Authentication
- OpenID Connect Adds Identity to OAuth 2
- Single Sign-On Is a UX Pattern
Full Transcript
Before a system can authorize or restrict anything, it first needs to know the identity of the requesttor.
Whether it's a user accessing our service through a browser or through mobile app or it's a third-party service trying to access our system. That's what
authentication does. It verifies that the user or service trying to access our system is who they claim to be. But here
is where most software engineers confuse or mix up concepts. They mix up authentication methods with authorization frameworks. They treat JWT
authorization frameworks. They treat JWT as an authentication method when in reality it's just a token format. They
also confuse the bearer authentication with JWT. They sometimes call OF2 an
with JWT. They sometimes call OF2 an authentication method when in reality it's actually an authorization framework. and they mix up single sign
framework. and they mix up single sign on with authentication methods when it's really a user experience pattern. In
this video, we're going to fix all of that by covering first of all what authentication is and then all the major types of authentication starting from
basic to digest authentication to API keys, sessions and cookies, bearer authentication and JWT tokens. What are
access and refresh tokens? Also, we'll
cover O of 2, open ID connect, also single sign on and identity protocols and understand what each one actually is and where this all fits. Let's first
understand what is authentication and then we'll get into the different authentication methods. So,
authentication methods. So, authentication really answers one simple question which is who the user is, whoever is trying to access our system.
Let's say you have your system like your API gateway, the layer of APIs, then your service layer and also the data storage. Before anyone can make requests
storage. Before anyone can make requests to your API gateway and start accessing services and data, they first need to be authenticated. That is where they send a
authenticated. That is where they send a login request. This comes either from a
login request. This comes either from a user or another service. This is where we confirm their identity if it's valid and grant access to our system to our
API gateway and all the other services or if the identity is not confirmed then we reject it with a 401 unauthorized response. This is the first step before
response. This is the first step before they will get into the authorization which is what they can access and what they can do once they can sign into your
system. But that's a separate discussion
system. But that's a separate discussion in itself. So in this one we are
in itself. So in this one we are primarily focusing on the authentication and different authentication methods that we can use to verify the user's identity. Now let's see the different
identity. Now let's see the different authentication methods that we have to verify the identity of the requesttor and let's start with the basic authentication methods. These are the
authentication methods. These are the basic of digest authentication API keys and session based authentication. Let's
start with the very first one on the list which is the basic authentication flow. This is the simplest form of
flow. This is the simplest form of authentication. Let's say you're making
authentication. Let's say you're making a request to the server to access some resource like API/ users to retrieve the user data. You will first receive an
user data. You will first receive an unauthorized response because you didn't provide the credentials. So we prompt the user or the service to provide credentials before accessing any
resource in the server. So in the upcoming request to the same resource they also provide the authorization header and this header contains the base
64 encoded version of the username and password for this user. This is where we verify it on the server side. If the
credentials are valid, then we respond with 200 okay status with the user data returned in the body or we unauthorize it again marking this as credentials
invalid. The problem with this method is
invalid. The problem with this method is that base 64 is easily reversible. So
this is an insecure method unless it is wrapped with HTTPS protocol and even then it's rarely used nowadays in production outside of the internal tools
because you're sending the credentials with every request and you're sending the base 64 encoded version which is not that secure. That's why we also have a
that secure. That's why we also have a digest authentication which is slightly better and it uses the MD5 hashing. So
this method works similar to the authentication with basic version. So
you are let's say trying to access the same resource like the users. It will
first respond with 401 unauthorized prompting you to include the credentials and then you'll make the same request but with the hashed response and that
will also contain the MD5 hash version instead of the plain password and username and same process as the previous one. If the credentials are
previous one. If the credentials are invalid, you will receive 401 unauthorized. Otherwise, you will
unauthorized. Otherwise, you will receive the successful response with the user data in the request body. This is
slightly better than the basic off as it uses the MD5 hashing, but it's still outdated and rarely used today because we have better options as you will see
soon. And if you're wondering how do we
soon. And if you're wondering how do we set these options in the authorization, for instance, if you're making the request from Postman or if you're doing this from the code, then you'll include
it as the header in the request. This is
where you can set the authentication type and you will notice the things that we're discussing here like the basic authentication which was the first version or digest authentication which
is the second version and you will see the other methods available here also the API key option and Postman calls all of these authentication types to just
keep it simple on the interface but that's also one of the reasons why developers get confused and they think that all of these are authentication types when some of them are
authentication methods, some of them are authorization frameworks. Next, we have
authorization frameworks. Next, we have API key authentication. This is where you generate a unique key for each client. Then then they send it with each
client. Then then they send it with each request to access the resources. So for
the same request as we discussed it comes to your API server first and it will include either authorization header or X API key and that will include the
API key that you generated for the user.
These API keys are typically stored in a database with key hash and also the scopes for the API key. And for
instance, if you ever tried to access APIs by generating a key on the dashboard and then it gives you the keyback which you can attach to the
requests that is where you already used the API key of that service to access the data. So if you included that key in
the data. So if you included that key in the request then the server will first do an API key lookup in the permissions or users table and if it's able to
verify that the API key is valid then we will authorize the request and send the successful response with the data in the response body otherwise the user will
get a 401 unauthorized response and if the key is missing overall like the authorization header or XAPI key then we just return a 400 bad request because
the API key is required to access this type of system. One issue with API keys is that if the key ever leaks, then anyone can use it and start accessing
the resources on your behalf with your API key and there is no built-in expiration unless you implement it yourself. Another thing is that this
yourself. Another thing is that this might seem similar to JSON web tokens, but API keys are just random strings with no embedded information. While in
JWT, we can store also information as you will see shortly. So the server here has no way to know who owns the key or what permissions they have without
looking it up in the database. Next, we
have the traditional web approach, which is the sessionbased authentication. This
is where a user logs in with their credentials and then we create a session in some sort of session storage. This
session storage can be as simple as just in memory like just a variable. But the
problem here is that we will lose it once the server restarts or crashes. The
other option is we can use tools like radius which is one of the most common ones in production because it's fast and it supports expiration for the sessions
or we can use a dedicated database here like SQL type of database. Another
option which is very rare is to use the file system of the server that you're using. The problem with this one is that
using. The problem with this one is that it's not scalable and overall radius is usually the go-to for production because it's fast and has built-in key
expiration. So with the first request,
expiration. So with the first request, we are fetching the session ID and then we set the session cookie on the client side. Then for any other upcoming
side. Then for any other upcoming requests that contain this cookie, we look up the session in the session storage here. And then if the session is
storage here. And then if the session is valid, we will get back the user data and we will send it with authorized response. Otherwise, if it's not found,
response. Otherwise, if it's not found, if we can't find the session, then this user is not authenticated. So, we send them an unauthorized response. One
challenge with session based authentications is that it is stateful, which means that the server must remember the sessions. We need to have some sort of session storage here. and
it works great for traditional web apps but cannot scale as easily for APIs or distributed systems. Now let's look at token based authentication. We'll cover
better authentication, JWT tokens, access and refresh tokens and how this compares to the sessionbased authentication. Instead of sessions,
authentication. Instead of sessions, modern applications usually use tokens.
So the client sends a token with each requests. For example, we have a login
requests. For example, we have a login with credentials where user will include their credentials in the authorization header which will include the type of
authentication which is bearer and also the token which we will validate on the server side. One thing developers
server side. One thing developers confuse here is the bearer token and JSON web tokens. Bearer token just means whoever has this token gets access. So
it's a pattern but not a specific method. And the most common type of beer
method. And the most common type of beer token is JWT, JSON web token. It's
basically a signed JSON object that contains the user ID or email for us to validate the user also expiration time and other claims as we need to store
them like roles, permissions and so on.
So what we do on the authentication server is we validate the credentials once we receive that authorization header and it is stateless meaning that
we don't need a database here to look up and that is why it's also scalable compared to the sessionbased authentication before the JWT let's say
revolution a token was just a string with no information and that token was sent and then this was looked up in some sort of database and only then we could
verify that the user has access. The
downside of that was that of course it's still stateful because we need the database access or cache which is required every time the token is used
with JSON web tokens. Now we can encode and verify by signing their own claims. And this is what now allows us to issue a short-lived JWT tokens that are
stateless, meaning they are self-contained and they don't depend on anybody else. They do not need to hit
anybody else. They do not need to hit the database and this reduces the database's load and it also simplifies the authentication process for the
server. So the first time we will
server. So the first time we will receive the credentials and validate the user and if it is valid we will generate the JSON web token and send it to the
client. From this point forward the
client. From this point forward the client can make requests and include this bearer token which is this authorization header that contains the
bearer authentication with the token and that token is most cases it is a JSON web token. we verify that signature
web token. we verify that signature locally without needing to hit the database. And if the token is valid, we
database. And if the token is valid, we return the requested data. Otherwise, we
return an unauthorized response. Modern
systems also use two types of tokens.
One of them is the access token and the other one is the refresh tokens. The
reason we need two tokens here is that access tokens are short-lived and they are used for API calls to the server while the refresh tokens are long lived
and they are used to get new access tokens basically to renew the access token. Whenever user sends a login
token. Whenever user sends a login request and signs in, they get both of these tokens. We generate an access
these tokens. We generate an access token that's valid for 15 minutes to 1 hour and we generate a refresh token that can last for days or even weeks.
Client now will use the access token to access the API and make the requests and it also stores the refresh tokens. One
important note here is that we never store it in local storage but we store it in HTTP only cookies. This prevents
us from XSS attacks on the client side.
And after this, user will stay logged in without re-entering credentials. If
their access token expires, they will get an unauthorized response. And this
is where we will use that refresh token which we stored to generate a new access token on the off server side. We can
make a request with that new token. And
this will successfully return us the data since we renewed the access token.
Next, let's get into Oaf 2 and open ID connect which are some of the misunderstood concepts and let's clarify whether these are authentication methods
or authorization frameworks and how they work. Oaf 2 is one of the concepts that
work. Oaf 2 is one of the concepts that is often misunderstood. It's an
authorization framework and not an authentication. So it answers what can
authentication. So it answers what can this app access on behalf of the user.
For instance, if you want to grant an application access to your Google Drive to be able to read your files from there, you would typically connect your
Google Drive for this external application and you're giving the app permission to access your data. The way
it works is it first will redirect you to consent screen from the Google of authentication and it will show you the permission request and if you allow
access for this application to be able to read the drive files on your behalf.
Then it will return the authorization code to this external application or it can also be your application. And the
way it works after that is that you exchange the code for token and you return the access token from Google Oaf to be able to read the data. That is the
confusing part because you're getting back an access token for the Google Drive API and you might think that this is an authentication method but the
access token just proves that the app can access your resources. But it
doesn't tell the app who you are. It
just proves that the app is allowed to access certain resources from your Google Drive. So after this point, the
Google Drive. So after this point, the application will be able to request files with that token and return the user files from Google Drive API. Next,
we have open ID connect which adds authentication on top of OAF2. So when
you click on sign in to Google let's say via your app it will redirect you to the authorization endpoint and this will show you the login screen where you
grant access to sign in to Google through your application. If you enter your credentials and consent then the provider will return the authorization
code and after this step your application will exchange the code for tokens and return the access token in combination with the ID token. From here
the access token is for O of2 authorization but the ID token is a JSON web token that contains your identity which includes your email or username
user ID which means that after this point your application is able to verify the signature and extract the user's identity to send the ID token for
verification to your back end. And by
having this ID token, your application can now create its own session and grant the access token for that user. This is
a modern solution. It's secure and also scales well. And that's also why most
scales well. And that's also why most applications nowadays use that type of authentication like sign in with Google, GitHub, Microsoft, and so on. And
lastly, let's cover single sign on and identity protocols. Single sign on is a
identity protocols. Single sign on is a user experience, not an authentication method. Which means that you're able to
method. Which means that you're able to login once but access multiple services.
For example, when you want to log to Google or octa, let's say you want to get access to your Gmail, to your Google Drive, to YouTube, to Google calendar,
you can do this by logging in once to the identity provider. Let's say it can be Google in this case. if you want to access these services and single sign on
uses identity protocols underneath to validate these sessions. So once you sign in with the identity provider let's say it's Google in this case your global
session is stored in a session storage and then you get back a single sign on cookie to your client to be able to access other resources. So let's say you
want to access Gmail for the first time then once you login you verify also the session and now you're able to access Gmail and for the next request if you
need to access Google Drive for the next one you don't need to login again because you have this cookie and the session stored in the session storage so we just verify your session and if it's
valid then you get access to Google Drive as well and similarly to YouTube to Google calendar and other services as I mentioned single signon uses identity
protocols underneath and these protocols are SL which is security assertion markup language or open ID connect both of these are identity protocols which
are used in combination with single sign on in case of SL to be able to access the app you're redirected to login and this is where we use SL for authentication
this is a common solution in enterprise and legacy systems like Salesforce, corporate dashboards and so on. It is an XML based protocol. So once you want to
sign in, you are redirected to login and then you get back the sample assertion in XML format and after that your identity is confirmed for the user and
now you're able to access the third party application. SL is still widely
party application. SL is still widely used but it's an older version compared to open ID connect. So the next option is the open ID connect as an identity
protocol. Let's say you want to access
protocol. Let's say you want to access an app and in this case it's Gmail. You
will be redirected to login to provide your credentials. And once you provide
your credentials. And once you provide your credentials, the user is authenticated. And now you get back the
authenticated. And now you get back the ID token in JSON web token format. And
this is what you will use for confirming your identity with Gmail. This is for instance what Google uses under the hood. and it's a more modern approach
hood. and it's a more modern approach compared to SL. But both of them are still very secure and relevant. These
are the most common types of authentication and that is just the first step for accessing our system.
After you know who the user is with authentication, you need to also know what they can do and what permissions they have. That is the part of
they have. That is the part of authorization. And I recommend you check
authorization. And I recommend you check out this video next to learn about the different authorization frameworks and how it works.
Loading video analysis...