DEV Community

Cover image for JWT: JsonWebToken demystified
khoinguyenkc
khoinguyenkc

Posted on

JWT: JsonWebToken demystified

Warning: This is not a how-to, but a what-is. Somebody already wrote a really nice how-to here: https://medium.com/@nick.hartunian/knock-jwt-auth-for-rails-api-create-react-app-6765192e295a
But I think it can be broken down to even simpler terms. We'll learn how you can use JWT in your backend and frontend. You'll learn it's rather simple. So read this guide before following the technical set-up guide above.


WHAT'S A TOKEN?

First off, before we even learn how these things work, let's get the big scary guy out of the way. We'll learn what a token is. It's not as scary as it looks. A token is just a piece of gibberish like "asdfqwertyjkl123". That's it. When we're carrying tokens it means we're carrying that piece of gibberish. And that piece of gibberish might translate to "username: brucewiththeboots, email: brucespringsteen2014@gmail.com".

The key thing is: you and I can't understand that. Nobody does besides JWT. JWT wrote that piece of gibberish and only JWT can understand it. Ahhhh.. So it's like a secret language. The secrecy of the language makes the piece of gibberish trustworthy. Whoever composed this "asdfghqwertyjkl123" - he must've been one of us. That's how JWT thinks. So JWT believes the content of the message.


Now that you have a concrete picture in your mind what a token is, hopefully you're more confident to dive in further and learn how we actually obtain such a token and what are they good for. We're gonna learn what the conveyer belt looks like. This is also not very complicated. But there will be several moving pieces. To see the big picture you need to look at them as a whole, at the same time. So my best advice to you is slow down. Slow way down. Take notes in physical paper and explain it to yourself aloud. It seems like overkill but it might just be the quickest and smoothest way to learn this.

Before we begin, keep in mind these 3 things:

  1. Don't question "how is this secure?". It's not. Nothing is 100% secure. You can evaluate how secure it is later. Also, don't be curious of the mechanism that churns out these gibberish code. You can find out on your own later. We've already got too much on our plate.
  2. Check your assumptions. You probably already have unconscious assumptions in your mind what an auth system look like. And when you learn about this new auth system, you instinctively assume this system also has these characteristics. But it might not. Which can lead to a wrong impression. So be cautious. Don't be that smug kid who thinks he knows what the teacher's going to say next.
  3. Don't take the metaphors too far. Metaphors help put a concrete image in your mind, but they're not perfect representations. If I say a lime is kind of like a lemon because they both are so and so, don't start extrapolating and thinking it's just like a lemon. Sounds silly, but we do it all the time.

Alright, time to dive in. Again, go slowly!

So our app will have the backend and the frontend.

We'll look at the backend first.

Before we begin, remember this: the backend does not keep track of sessions. It does not "log people in". It does not keep track which user is logged in. It is much more simple than you think. Now we're finally beginning for real.


Diagram Flow Illustration
BACKEND

Our backend consists of just 2 things: the auth booth and the vending machine.

1.auth booth

The auth booth is kind of like a booth that you check in as you attend a conference. Then they might give you a lanyard with your name and picture on it. Similarly, the auth booth issues a token to the front end as you login. The frontend might send data like {username: "brucewiththeboots," password: "drowssap"} to mywebsite.com/api/auth, the auth booth will verify those credentials are correct. If correct, the auth booth delivers a token like "asdfqwertyjkl123" to the frontend.

The name on the lanyard is a trustworthy ID card. why? if you have a lanyard, it indicates you signed in at the booth. The guy working at the booth verified you paid your tickets and wrote your name down before giving it to you. It means the name on your lanyard is indeed your name (If we assume the lanyard is impossible to fake and hard to steal from other someone else). Your token "asdfqwertyjkl123" is your lanyard. It's also trustworthy like the lanyard because it's impossible to fake and hard to steal. The difference is, the lanyard can be read by anybody, whereas the token is a secret language. So it's definitely not a perfect metaphor.

summary: auth booth takes username and password, send token down

  1. vending machine

Our backend will be an api. And what are api's anyway? They're essentially json vending machines. For example, the backend receives a request likes animalphotos.com/api/q?type=cat&amount=35. It delivers a json that includes data to 35 cat pictures.

An api that uses JWT will also receive a request with the url like animalphotos.com/api/q?type=cat&amount=35, but that request will also include a token like "asdfghqwertyjkl123".

Our backend will relay this request to the vending machine. The vending machine read this request , translate the secret language and realize the token says it's brucewiththeboots and he wants 35 cat pictures. It can then decide whether to send him 35 cat pictures. Perhaps he already requested 300 pictures earlier and reached his daily limit. So it won't send down any cat pictures. Or perhaps he's getting more cats.

Or, another example, facebook receiving a request with url facebook.com/api/q?datatype=photos&id=19834872323 with a token asdfghqwertyjkl123. That means brucewiththeboots wants access to a certain picture. The api can decide whether he's granted access. He might be authorized to see it or he might not.

To extend the lanyard-at-a-conference metaphor: the lanyard means you're allowed to attend the lecture from the speaker. You're entitled to the free drinks and lunch offered. You're allowed to use their spotless restroom. Our vending machine also checks your token/lanyard to determine whether to serve you cat pictures.

And that is basically what the vending machine does. It uses the token to find out who's requesting. It verifies if this person is authorized to receive the photos. Then it delivers accordingly. A request that doesn't come with a token will be rejected. Nothing will get delivered.



FRONTEND
I just sketched a rough picture of what the backend looks like. You only need these two parts to make it work! From here, you can vaguely imagine the role of the frontend.

Let's visualize the flow of the frontend:

It simply sends up your username and password, receives a token, and then keeps that token somewhere. For example, in localStorage. And how does it keep track of a session? It does not not need to keep track of the username at all. Instead, it just keeps the token! The presence of a token indicates the user is logged in. That token will be all that the frontend needs!

Your frontend will use that token on every single fetch request to the backend. For example,

fetch( animalphotos.com/api/q?type=cat&amount=35, { 
        method: "GET",
        headers: {
          "Content-Type": "application/json",
          "timerange": "recent",
          Authorization: `Bearer asdfghqwertyjkl123`
        }
      }
)
Enter fullscreen mode Exit fullscreen mode

The backend reads the token, realizes it's brucewiththeboots, and decides if Bruce is authorized to access that particular content.

As long as you stay logged in, it will keep that token.

As you log out, it will delete the token. Next time you log in, it will use your username and password to get a brand new token. it won't say "asdfqwertyjkl123". it will be "oawifsdaklfsdafsd237842" for example, but that message also translates to "brucewiththeboots"


And those are all the parts ! Nothing insane. But takes a while for everything to sink in. Just stare at the picture for a bit. Redraw them without looking and start teaching yourself aloud like a crazy person. And suddenly, things will click.

Discussion (0)