Authentication is one of the core functions of applications on the internet today, one that many developers are familiar with. Yet, actually implementing authentication correctly requires understanding several standards and protocols.
Two of the most important of these authentication standards are OAuth and JWT (JSON Web Tokens).
Looking to make sense of OAuth and JWT? You’re in the right place. In this article we will cover:
What OAuth is and the Pros and Cons of using it
What JWT (JSON Web Tokens) is and the Pros and Cons
How to use OAuth and JWT together effectively
Let’s dive in!
OAuth (Open Authorization) - often written as the latest version OAuth 2.0 - is a protocol that is used to authenticate a user via an authentication server.
One of the useful things about OAuth is that it enables you to delegate account access in a secure way without sharing credentials. Instead of credentials, OAuth relies on access tokens.
Using access tokens, a client application can verify the identity of the user that authenticated themselves.
Visually, the process looks like this:
When you implement "Sign in with Google" or "Sign in with Github", you are using the OAuth 2.0 protocol!
Working with OAuth has some great benefits, including:
It’s the accepted industry standard. This means that most authentication services will understand and use OAuth 2.0.
There are many plug-and-play OAuth options. Including services like "Sign in with Google" and "Sign in with Facebook" that are already set up to be consumed within your application.
OAuth has well-tested client libraries in almost all languages and web frameworks. This means that your language of choice can be used with OAuth
It allows for the decoupling of code. Your client application code is not affected by the authentication code.
OAuth is very secure and battle-tested. Due to its widespread nature, you can rest assured that all security edge cases have been thought about by industry experts.
While OAuth is a great standard, there’s a handful of things to be mindful of when using it:
OAuth can be complicated to understand if you are unfamiliar. There are several different OAuth flows and deciding which is right for you can be a challenge. Sometimes, you may even need to use multiple flows.
It has lower end-user privacy. The auth server knows all the sites that the end-user has logged in to. For example, when a site uses Sign in with Google, Google would be able to keep track of when that site’s users are signing in or are active.
It’s overkill in certain situations. If you are building a simple web app that has one frontend and backend, then you don’t need the OAuth protocol. However, a lot of online tutorials and ready-made auth solutions force you to implement this.
No session management solution. Once the user is authenticated, the auth server simply returns a JWT which can be consumed by your application (as well will see later). However, after that step, the OAuth protocol doesn’t provide any support for specifying how to maintain the authenticated session between your app’s frontend and backend - this is totally up to the developer.
A JWT is a token that is generated by the authentication server and contains the end-user’s information (like their userID, email, etc.). The information is in JSON format and can be efficiently verified by the client application using cryptography.
JWT is best used whenever you want to transmit some information to an untrusted client, in such a way that that client can verify the information contained in the payload themselves.
From the context of an auth server, an untrusted client is an application that the user is trying to use. From the context of the application’s backend, an untrusted client is the frontend code.
There are some good reasons JWT is such a popular standard:
They are self-contained. The JWT can contain the user’s details. So you don’t need to query a database/auth server for that information on each request.
They offer strong security guarantees. JWTs are digitally signed which safeguards them from being modified by the client or an attacker.
JWTs are stored only on the client. You generate JWTs on the server and send them to the client. The client then submits the JWT with every request. This saves database space.
They are efficient and quick to verify. This is because JWTs don’t require a database lookup.
While JWTs are incredibly useful - it’s helpful to keep the following things in mind:
You can’t revoke them without putting in a lot of extra engineering effort. This is because there is no db call when verifying them. In order to implement immediate revocation, you would need to implement JWT blacklisting which can be time-consuming.
It’s easy to create security bottlenecks while keeping one secret safe. If the signing key is compromised, the attacker can use that to create their own valid JWTs. This would allow them to spoof the identity of any user and application.
We’ve learned that OAuth and JWT are powerful standards for building authentication flows in applications. As it turns out - OAuth vs JWT doesn’t have to be either or - they can be used together!
When the authentication server successfully verifies a user’s credentials (via OAuth) it also needs to transmit the user details to the client application. In order for the client application to verify the details, JWTs can be used to ensure an efficient process.
This works by the OAuth server sending a JWT to the client (after the OAuth flow is complete) containing the end user’s information.
A typical JSON payload in the JWT sent by the OAuth server looks like the below (example from sign in with Google):
{
"iss": "https://accounts.google.com",
"azp": "1234987819200.apps.googleusercontent.com",
"aud": "1234987819200.apps.googleusercontent.com",
"sub": "10769150350006150715113082367",
"at_hash": "HK6E_P6Dh8Y93mRNtsDB1Q",
"email": "[email protected]",
"email_verified": "true",
"iat": 1353601026,
"exp": 1353604926,
"nonce": "0394852-3190485-2490358",
"hd": "example.com",
}
What do all these fields mean? Below is a quick summary using this particular example:
is: The issuer of the token (in this case Google)
azp and aud: Client IDs issued by Google for your application. This way, Google knows which website is trying to use its sign-in service, and the website knows that the JWT was issued specifically for them.
sub: The end user’s Google user ID
at_hash: The hash of the access token. The OAuth access token is different from the JWT in the sense that it’s an opaque token. The access token’s purpose is so that the client application can query Google to ask for more information about the signed-in user.
email: The end user’s email ID
email_verified: Whether or not the user has verified their email.
iat: The time (in milliseconds since epoch) the JWT was created
exp: The time (in milliseconds since epoch) the JWT was created
nonce: Can be used by the client application to prevent replay attacks.
hd: The hosted G Suite domain of the user
As you can see, there is a lot of information transmitted from the OAuth server (Google in this case) to the client application! It’s worth mentioning that some of the fields in the above JSON payload are specific to Google (like hd). Other providers may have similar and different content.
Since this is all in a JWT, the client application can verify the contents of this JSON and know that no one has manipulated this content.
Oftentimes we see developers asking whether to use "OAuth or JWT" for their authentication setup. In reality, OAuth and JWT are two different standards, with different uses, which can be used together with great effect. In fact, JWT is often used as part of the OAuth protocol.
At SuperTokens, we provide an auth solution that mitigates most of the cons of using OAuth and a JWT, including:
We encourage the use of OAuth only when really needed.
We offer a way to revoke JWTs / access tokens easily without reducing the verification efficiency.
We offer a secure session management solution which is the missing piece in the OAuth protocol.
Written by the Folks at SuperTokens — hope you enjoyed! We are always available on our Discord server. Join us if you have any questions or need any help.