Five easy steps to understand JSON Web Tokens (JWT)

jwt


I present to you my rather free translation of article 5 Easy Steps to Understanding JSON Web Tokens (JWT) . This article will talk about what JSON Web Tokens (JWT) are and what they eat. That is, what role do they play in user authentication and application data security.


First, consider the formal definition.


JSON Web Token (JWT)Is a JSON object that is defined in the open standard RFC 7519 . It is considered one of the safest ways to transfer information between two participants. To create it, you need to define a header with general information on the token, payload data, such as the user id, his role, etc. and signatures.
By the way, correctly JWT is pronounced as/dʒɒt/

In simple words, JWT is just a string in the following format header.payload.signature.
Suppose we want to register on a site. In our case, there are three participants — the user user, the application server, application serverand the authentication server authentication server. The authentication server will provide the user with a token, with the help of which he will later be able to interact with the application.


How the application uses JWT to verify user authentication.


The application uses JWT to verify user authentication as follows:


  1. First, the user accesses the authentication server using an authentication key (it can be a username / password pair , or a Facebook key, or a Google key, or a key from another account).
  2. The authentication server then creates the JWT and sends it to the user.
  3. When the user makes a request to the application API, he adds the previously received JWT to it .
  4. When a user makes an API request, the application can check whether the user is impersonating what was transmitted with the JWT request . In this scheme, the application server is configured to be able to check whether the incoming JWT is exactly what was created by the authentication server (the verification process will be explained later in more detail).

JWT structure


JWT consists of three parts: header header, payload payloadand signature signature. Let's go through each of them.


Step 1. Create a HEADER


The JWT header contains information on how the JWT signature should be calculated . A header is also a JSON object that looks like this:


header = { "alg": "HS256", "typ": "JWT"}

The field typdoes not tell us anything new, only that it is JSON Web Token . More interesting here is the field algthat defines the hashing algorithm. It will be used when creating the signature. HS256- Nothing but, HMAC-SHA256for its calculation, you need only one secret key (more about this in step 3). Another algorithm can also be used RS256- unlike the previous one, it is asymmetric and creates two keys: public and private. Using a private key, a signature is created, and using a public key, the authenticity of the signature is only verified, so we do not need to worry about its security.


Step 2. Create PAYLOAD


Payload is the payload that is stored inside the JWT . This data is also called JWT-claims . In the example we are considering, the authentication server creates a JWT with information about the user id - userId .


payload = { "userId": "b08f86af-35da-48f2-8fab-cef3904660bd" }

We put only one claim (claim) in the payload The . You can put as many applications as you want. There is a list of standard applications for JWT payload - here are some of them:


  • iss (issuer) - defines the application from which the token is sent.
  • sub (subject) - defines the topic of the token.
  • exp (expiration time) - token lifetime.

These fields may be useful when creating a JWT , but they are optional. If you want to know the entire list of available fields for JWT , you can take a look at the Wiki . But it is worth remembering that the more information is transmitted, the greater the result will be the JWT itself . Usually there are no problems with this, but still, it can negatively affect performance and cause delays in interacting with the server.


Step 3. Create SIGNATURE


The signature is calculated using the following pseudo-code:


const SECRET_KEY = 'cAtwa1kkEy'
const unsignedToken = base64urlEncode(header) + '.' + base64urlEncode(payload)
const signature = HMAC-SHA256(unsignedToken, SECRET_KEY)

The base64url algorithm encodes the header and payload created in steps 1 and 2 . The algorithm concatenates encoded strings through a dot. Then, the resulting string is hashed by the algorithm specified in the header based on our secret key.


// header eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
// payload eyJ1c2VySWQiOiJiMDhmODZhZi0zNWRhLTQ4ZjItOGZhYi1jZWYzOTA0NjYwYmQifQ
// signature -xN_h82PHVTCMA9vdoHrcZxH-x5mb11y1537t3rGzcM

Step 4. Now combine all three JWT components together


Now that we have all three components, we can create our JWT . It is quite simple, we connect all the received elements into a line through a dot.


const token = encodeBase64Url(header) + '.' + encodeBase64Url(payload) + '.' + encodeBase64Url(signature)
// JWT Token
// eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiJiMDhmODZhZi0zNWRhLTQ4ZjItOGZhYi1jZWYzOTA0NjYwYmQifQ.-xN_h82PHVTCMA9vdoHrcZxH-x5mb11y1537t3rGzcM

You can try to create your own JWT  Online jwt.io .
Let's get back to our example. Now the authentication server can send to the JWT user .


How does the JWT protect our data?


It is very important to understand that using JWT does NOT hide or mask data automatically. The reason why JWTs are used is to verify that the data sent was indeed sent by an authorized source. As demonstrated above, the data inside the JWTencoded and signed, note that this is not the same as encrypted. The purpose of data encoding is structure transformation. Signed data allows the data recipient to verify the authentication of the data source. Therefore, encoding and signing data does not protect them. On the other hand, the main purpose of encryption is to protect data from unauthorized access. For a more detailed explanation of the difference between encryption and encryption, and how hashing works, see this article . As JWT only encrypted and signed, and because JWT is not encrypted, JWT not guarantee any security for sensitive (sensitive) data.


Step 5. Checking JWT


In our simple example of 3 participants, we use JWT , which is signed using an HS256algorithm and only the authentication server and application server know the secret key. The application server receives the secret key from the authentication server during the installation of authentication processes. Since the application knows the secret key, when the user makes an API request with the token attached to it, the application can perform the same JWT signing algorithm as in step 3 . An application can then verify this signature by comparing it with its own calculated hash. If the signatures match, then JWTvalid, i.e. came from a trusted source. If the signatures do not match, then something went wrong - perhaps this is a sign of a potential attack. Thus, by checking the JWT , the application adds a layer of trust between itself and the user.


Finally


We went over what JWTs are , how they are created and how they are validated, how they can be used to establish trust between the user and the application. But this is only a piece of the puzzle on a large topic of authorization and protection of your application. We considered only the basics, but without them it is impossible to move on.


What's next?


Think about security and add Refresh Token. See my next article on this topic .


useful links


  1. 5 Easy Steps to Understanding JSON Web Tokens (JWT)
  2. Securing React Redux Apps With JWT Tokens
  3. Why do I need Refresh Token if I have Access Token?

Also popular now: