This is a brief introduction to JWT (JSON Web Token).

What is JWT

JWT, full name JSON Web Token,
is an easy-to-use, stateless way of authentication (Authorization).
Simply put, it’s
the Server encrypts JSON data into a token to authorize the Client.

Words are pointless, here’s the code, a chestnut example.

After the Client logs in,
the Server has to return a token valid for 7 days.
The corresponding Python sample code would look like this:
(Uses the PyJWT package: pip install pyjwt)

import time

import jwt

exp = int(time.time()) + 86400 * 7  # expiration time
user = 'liriansu'  # user identifier
key = 'hunter2'  # secret key
payload = {'exp': exp, 'user': user}  # JSON data
token = jwt.encode(payload, key)

print(token)
# the token might look something like this
# eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.EoKoMCjq_zGqUg5HDfqw4EN7EiG6gMjkUZle0uGJDGU

There’s a meme about hunter2: the weak password hunter2

Then the Client carries the token in the authorization header or query string each time.
When the Server receives the request,
just use payload = jwt.decode(token, key) to verify the permission.
After successful verification, payload is the whole JSON data.
In theory you can put any non-sensitive data into the token payload.

So, in summary,
if you use JWT as authentication,
it has the following characteristics:

  1. The Client doesn’t need to worry about any encryption/decryption, just stores the token and carries it in requests.
  2. The Server can implement authentication without depending on external storage, all data is in the token.
  3. That is to say, this step of authentication doesn’t need a database like File/MySQL/Redis to know the user identity.
  4. Because the token has an expiration time, you need to refresh the token before/after it expires.

OK, that’s all the description about JWT.
This brief introduction ends here. (foggy)
(Although last time’s introduction to Hawk was roughly like this too)

More about JWT

You’ve talked so much, essentially it’s using a piece of JSON data as a token.
Is this broken token really safe? Can it be forged?

emmmmmm, good question (means the question is sharp, hard to answer head-on, preparing a detour)
JWT is widely used, battle-tested, everyone’s using it (which shows I also don’t really know, probably no problem? — a kind of herd mentality)

Seriously, my personal opinion:
First, if the token/key is leaked,
the consequences are basically as serious as with other authentication methods.
Second, JWT can choose appropriate encryption methods,
plus an appropriate key, it’s basically unforgeable.
Also, outside of JWT,
you absolutely must use HTTPS!
Not using JWT is like not having access control;
not using HTTPS is basically like not wearing underwear

I want to know more details about JWT generation/verification

For specifics please refer to the source RFC7519 - JSON Web Token (JWT)

Simply put, JWT consists of the following three parts:

  1. The first part specifies the encryption algorithm (alg) and token type (typ).
  2. The second part is the payload we defined.
  3. The third part is the signature produced by the encryption algorithm.

After getting the three parts of data,
encrypt each with base64,
remove the trailing equal signs,
join them with periods,
and that’s a token.
Verification is basically just reversing this process.

Whoa, so the information in the token is in plaintext?

Yes.
So don’t put any sensitive information in the token.

The doc calls the information in the payload Claim.
There are several optional Claims:

  • iss: Issuer.
    For example, if this token is issued by WeChat,
    it could be {'iss': 'wechat'}

  • aud: Audience, the recipient.
    For example, if King of Glory wants to log in with WeChat,
    it could be {'aud': 'king-of-glory'}

  • exp: Expiration Time.
    Uses integer Unix timestamps.
    For info on timestamps see “Dates and Times on the Internet”

There’s something fun in RFC7519:
each of the above Claims ends with the sentence Use of this claim is OPTIONAL
(RFC2119 also defined what OPTIONAL means)

That means we can throw anything into payload.
As long as we follow this kind of encryption/decryption/authentication approach,
we can say “we use JWT.”

Won’t the token be very large?

It might be.

So put as little as possible in the payload.
Look at the doc, even issuer -> iss, audience -> aud had several characters saved.

Also, when transmitting JWT,
compared to putting it in query string,
it’s more recommended to put it in Request Headers.

Comparison with other authentication methods

A thorough comparison is beyond the scope of this article.
(It feels great to write this sentence, saves looking up ten thousand resources)
Below let me use a simple table to compare the few authentication methods I’m familiar with:
JWT, OAuth, Session, Hawk

JWTOAuthSessionHawk
Ease of useEasy, just a tokenAnnoying, need to use Refresh Token to refresh Access TokenEasy, just use CookieAnnoying, every request needs separate header computation
VersatilitySuits all sorts of scenariosEspecially suited for scenarios with third-party authorizationIt’s alright…Suits anywhere headers can be used
SecurityRoughly the same as other schemes, if key leaks you’re doneAuth Server just needs to be secure, I don’t care about Client otherwise similar to other schemesIt’s alright…I! Can! Defend! Against! Man-In-The-Middle attacks!
AcceptanceHas some level of security, clients love it, used a lotA compromise between cumbersome and secure, many big companies use itTruly widespread…So far only heard my company uses Hawk

Other thoughts

  • JWT’s full name is JSON Web Token,
    careful not to write variable names like jwt_token (semantic redundancy).

  • RFC7519 also defined that JWT is pronounced like jot.
    However in actual conversation everyone says JWT (afraid of not being understood).

  • JWT says you can use just one key,
    but in our actual project we still used different keys for different users.
    (We also used a database)

  • If the payload has an expiration time,
    in theory JWT doesn’t expire after issuance.
    That is, the Server can’t manage these tokens.
    (So you can add a database to manage them)
    (Looks like it got complex)

  • If you want to do “remember login state” with JWT,
    you can set the token expiration to, say, 7 days,
    then refresh the token every time the user logs in each day.
    This way unless the user hasn’t logged in for a week,
    they won’t have to log in again.

  • My knowledge of internet security is really limited.
    Often when I read the docs,
    I learn three or four new terms in one sentence.
    Still need to learn more.
    As they say gou ri xin, ri ri xin, you ri xin (if you can renew yourself one day, do it daily, and keep renewing yourself).