JSON Web Tokens (JWT) is very popular today. Especially in Web development.

  • popular
  • security
  • stable
  • Easy to use
  • Support JSON

All these factors have made JWT famous.

However, today I’m going to talk about the disadvantages of using JWT. That’s why using JWT for session control is so bad.

Why use JWT?

If you don’t know JWT, don’t panic, it’s not scary.

JWT simply implements a JSON-based standard for passing declarations between networks.

For example, I am blind and hard of hearing. You bought my lunch last week, and NOW I need your account number to pay you back. If I ask for your account number and someone else shouts theirs, I may accidentally send money to someone else because I mistake someone else’s account for yours.

JWT aims to prevent this from happening. JWT provides an easy way to verify who created the data first as they pass it to each other.

So, like the example above, even if I receive more than a million JWT accounts back, I can easily tell which one really came from you.

How does JWT work?

JWT is an encrypted string in JSON format.

At the heart of JWT is the key, which is JSON data. This is the data you care about and want to pass on safely. How JWT does this, and makes you trust it, is encrypted signatures.

For example, if I write a letter, when I sign it, it means that anyone who has read it knows that I wrote the letter. And my signature is unique, so it can’t be doubted. Cryptographic signatures are roughly the same, and JWT has two types of encryption: symmetric and asymmetric, both of which are equally effective.

JWT content encryption

In fact, the content of JWT (the internal JSON data) is usually unencrypted. This means that data within the JWT can be viewed without a key. JWT does not encrypt your data by default, it just helps you verify that someone you trust created it.

If you really need to encrypt JWT content, you can do so using JWE, but this is not common. Make sure you use the correct method.

How are people using JWT today?

The most common use of JWT is for authentication. There are a number of Web security libraries that use JWT to create session controls, API tokens, and so on.

Typically, when a site/API needs to be authenticated, the server generates a JWT containing the user ID, along with some other critical information, which is then sent to the browser/client, etc., and stored as a session token.

For example, when a user visits another page on a web site, the browser automatically sends the JWT to the server, which verifies that the JWT is the same as the token originally created, and then allows the user to perform subsequent actions.

Not bad in theory, because:

  • When the server receives a JWT, it can verify that it is legitimate and a token for a trusted user
  • Can be authenticated locally on the server without any other network requests, communication with the database, etc. This can make the administration session more efficient, since you don’t need to load user information from the database (cache) and only need to run a small amount of code locally. This is probably the biggest reason people like using JWT.

Seems like a great way to improve the performance of your Web application while reducing the load on your cache and database servers and providing a better experience. In addition, you can store user permissions, user profiles, and other additional information in JWT to further reduce database stress.

Why is JWT not the best session token?

Now that we’ve seen how JWT is used for authentication, let’s move on to the central topic of this article: why JWT is not the best session token, and why plain old sessions are better than JWT in almost every way.

background

Let’s start with some background. Most sites built by developers are relatively simple:

  • User registration
  • The user login
  • The user clicks to perform the operation
  • Websites use user information to create, delete, update, and view information

For these types of sites, be aware that each page a user interacts with contains some dynamic data. For example, if you are visiting a site that requires users to log in to further their operations, you will often perform these operations on users in the database:

  • Records the operations being performed by the user
  • Add some information about the user to the database
  • Check the user’s permissions to see if the user can perform an operation
  • , etc.

data

Let’s look at two options:

  • Store the user ID in the Cookie (abc123)
  • Store user IDS in JWT (abc123)

If we store the ID in a Cookie, it takes 6 bytes. If you store the ID in JWT (setting up the basic request header fields, among other things), you need a few hundred bytes or more. For simple session control, the number of requests per page increases tens of times.

If your site has 100,000 browsers per month, that means tens of megabytes of extra traffic. That may not sound like much, but it can add up over time. In fact, many people store more information in JWT.

You need to manipulate the database anyway

As mentioned above, most sites that require users to log in are primarily CRUD operations that generate dynamic content.

When using JWT on a website, for almost all pages loaded by the user, user information needs to be loaded from the cache/database, and the following situations can occur:

  • User critical information needs to be queried (e.g. does the user account have sufficient funds to complete the transaction?).
  • Some information needs to be saved into the database (for example, unique information about the user, against which the user needs to be retrieved)
  • Complete information must be queried from the cache/database to facilitate the site to generate complete dynamic page content.

Think about whether or not your site might encounter any of these situations. This means that most sites do not apply to the stateless nature of JWT. To solve this problem, the JWT would need to become larger and the CPU would need to compute the signature, which would result in a much slower session than traditional sessions.

In fact, almost every Web framework supports passing in user information on every request, including Django, Rails, express.js, etc. (if it’s useful for authentication). In addition, if you use a Memcached/Redis server to cache user information, retrieval is very fast.

Redundant signature

One of the selling points of JWT is encrypted signatures, which allow the recipient to verify that JWT is valid and trusted.

However, virtually every framework over the last 20 years has been able to get good cryptographic signature processing for ordinary session cookies. This means you can get exactly the same effect as JWT, and in most Web authentication applications, JWT is stored in cookies, which means you have two levels of signature.

Sounds great, but there’s no advantage, and to do that, you need to spend twice as much CPU to validate the signature. This is not ideal for Web applications with stringent performance requirements, especially for single-threaded environments.

What’s a better solution?

If you’re building these types of sites, it’s best to opt for old, simple and secure server-side sessions. Rather than storing the user ID in JWT and then storing the JWT in Cooike. Simply store the user ID directly into the Cookie.

If your site is popular and gets a lot of traffic, you can cache your sessions into Memcached/Redis, and it’s also good for scaling your service.

When to use JWT?

JWT is not useful for most sites, but there are several situations where it can be useful.

If you are building API services from server to server or client to server (e.g. mobile APP or single page APP), using JWT is very wise. Such as:

  • Your client needs to authenticate through the API and return JWT
  • The client then uses the returned JWT authenticated to request other API services
  • These other API services verify through the client’s JWT that the client is trusted and can perform certain operations without revalidation

JWT is a good fit for this type of API service because the client needs to make frequent requests, permissions are manageable, and authentication data is typically persisted in a stateless manner without much reliance on user information.

If you’re building an application like single sign-on or OpenID Connect authentication, JWT is also a good place to implement a way to authenticate users with a third party.

conclusion

When you’re ready to build your next site, just use the Web framework’s default authentication functionality and no longer need to integrate JWT.


Follow the public account “Zhanbai Saio” for more valuable information.