Using JWT tokens

The mechanism of securely authenticating whether a request comes from an authorized source has been simplified greatly with the introduction of the JSON Web Token (JWT) standard, which is described in the open standard RFC 7519. The idea behind JWT is that a standard JSON object is encrypted using a secret key. This encryption process is known as signing a token. Only a holder of the secret key can verify that this token is valid. In other words, a server creates a token using its secret key, and then any request that comes into the server can verify that the token was signed correctly. JWT tokens are therefore stateless, and can be used quite easily in a load-balanced environment. As long as all servers that are within the load balanced cluster know what the secret key is, they can all validate an incoming token, irrespective of which server generated it. JWT tokens can also be configured to have an expiration time, and can, therefore, be valid for a short period of time.

In the stateless world of REST endpoints, we will need to ensure that only valid users of our systems are able to access certain endpoints. We can easily configure our endpoints to require a JWT token, and then validate that it was issued using the correct key before taking action.

In this section of the chapter, we will show how to issue and validate JWT tokens. One of the popular libraries that are available for working with JWT tokes is called jsonwebtoken. We can install the jsonwebtoken library for working with JWTs from npm as follows:

npm install jsonwebtoken  

The first part of working with JWT tokens is to actually create one. Remember that in order to create a token, we need to have a secret. This secret should not be visible to anyone other than the server that is creating tokens, so it is best that we create our tokens in our Express server.

Let's update our Express login router to create and sign a JWT token as follows:

import * as jwt from "jsonwebtoken"; 
const jwtSecret = '0e4253ef-5e4f-4d62-8eeb-c80e36a68c8a'; 
 
router.post(`/login`, (req: any, res: any, next: any) => { 
    serverLog(`POST /login`); 
 
    if (req.body.username && req.body.username.length > 0 
        && req.body.password && req.body.password.length > 0) { 
 
        let user_context = { 
            username: req.body.username, 
            token: '' 
        } 
 
        var token = jwt.sign(user_context, jwtSecret); 
        user_context.token = token; 
        res.json(user_context); 
 
    } else { 
        serverLog(`/login - Error : Invalid username or password`); 
        res.status(401).send('Invalid username or password'); 
    } 
 
}); 

Here, we have imported the jsonwebtoken library and named it jwt. We then create a variable named jwtSecret, and assign a GUID string to it. This is the secret that the server will use to sign the JWT token.

In our post handler, we create a JavaScript object that has a username property. This will be the contents of our token. We then use the sign function from the jwt library, passing in the JavaScript object as the first argument, and the secret as the second object. Once the object is signed, we simply return it. That is all there is to creating a JWT token. We simply create a standard JavaScript object, and then use the library to encrypt and sign the object.

Let's log in to our application now, and take a look at this token. If we navigate to our Developer tools, and open the Application tab, we can see the token that is stored in Local Storage. It is simply a string as follows:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImF1c2VybmFtZSIsImlhdCI6MTU0NzcwOTg2NX0.ciS4MqQxxx8eCf2zXoAqGPlf6DS_Jo8JuEpB11qLPuA

The interesting thing about JWT tokens is that anyone can decode them, but only the server with the secret that was used to sign it can verify the token. As an example of how to decode this token, let's head over to the website at jwt.io, and simply paste this string into the Encoded text box as follows:

Here, we can see that the JWT token has been decoded, and shows us the actual payload on the right-hand side. This payload includes our username property,  as well as the iat property, which indicates when the token will expire. Note that we did not need to let the website know what the secret was in order for it to decode the token. This is what is meant by anyone can decode a token, but only the server with the secret key can verify it.

The open nature of JWT tokens means that we cannot store any sensitive information within a JWT token. If we were to store our password, for instance, then anyone could gain access to the token and decode it to figure out our password.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.59.34.87