What is a JSON Web Token? (JWT)


JSON Web Tokens (JWT) are a way to securely transmit data in a neat and compact JSON object. JWTs are an open standard (RFC 7519) and can securely send the data using private key signing. Private key signing allows data to be authenticated by the receiver with a public key.

Although JSON Web Tokens can also be encrypted to provide secrecy between two parties,we will be focusing on signed tokens. Signed tokens are very useful as they provide a way for the receiving party to verify the claims within the token.

Some of the essential concepts of a JWT are:

Compact: JSON Web Tokens are incredibly compact. This allows them to be sent in something as simple as a URL. Because their size makes them so agile, they can be used in almost any situation.

Self-contained: The JWT contains every piece of information needed about the user. This avoids the need to call the service or database more than is necessary.

JWT Structure

The JWT consists of 3 components:

  • Header
  • Payload
  • Signature

If you put the components together a very generic JWT looks like this:

aaaaa.bbbbb.ccccc

Letโ€™s take a look at the different components:

Header

The header normally consists of two parts. The alg (Algorithm) and the typ (Type of token), which is JWT.

Header Object:
object
alg
string
typ
string
Warning

The Zoom API uses HS256. Use of other algorithms may produce unexpected results.

Payload

The second part of the token is the payload, which contains claims. Claims are pieces of information being passed on about the user, along with any metadata that needs to be passed as well. There are three types of claims: registered, public, and private.

Registered Claims: Claims that are predefined by the JWT spec. They are highly recommended because they are meant to be interoperable between services.

Examples of registered claims:

  • iss (issuer)
  • exp(expiration time)
  • sub(subject)
  • aud (audience)

Public Claims: Used as needed by services using JWTs. These should be defined in the IANA JSON Web Token Registry or as a URI that has a namespace that wonโ€™t generally collide.

Private Claims: Custom claims created to share information between parties that agree on using them and are neither registered nor public claims.

Below is an example Zoom payload:

Example Payload:
object
iss
string
required
exp
integer
required
Note

The expiration time (exp) can be defined in a numeric date time format.

The payload is then Base64Url encoded to form the second part of the JSON Web Token.

Though protected against tampering, the information contained in the header and payload is readable by anyone. Do not put secret information in the payload or header elements of a JWT unless it is encrypted.

Signature

To create the signature section of the JWT, use the encoded header and payload with the Secret and HMACSHA256 algorithm to sign the entire package.

For example:

HMACSHA256( base64UrlEncode(header) + โ€œ.โ€ + base64UrlEncode(payload), secret)

Conclusion

Just like JSON Web Tokens, this introduction to them is compact. A beneficial resource for developing with JWT are JWT.io. libraries.

Supported Libraries

As of today, we support jwt.io libraries. While other libraries can create JSON web tokens, the jwt.io libraries are the most robust. Please make sure to use the libraries on jwt.io.

We also have a great article about using Postman and JWT to get started very quickly with our APIs.

Here is a sample Node.JS app that uses JWT to make API calls to Zoom - https://github.com/zoom/zoom-api-jwt

Node App using JWT to call Zoom APIs
const jwt = require('jsonwebtoken');
const config = require('./config');
const rp = require('request-promise');

const payload = {
    iss: config.APIKey,
    exp: ((new Date()).getTime() + 5000)
};

//Automatically creates header, and returns JWT
const token = jwt.sign(payload, config.APISecret);


var options = {
    uri: 'https://api.zoom.us/v2/users',
    qs: {
        status: 'active' // -> uri + '?status=active'
    },
    auth: {
    		'bearer': token
  	},
    headers: {
        'User-Agent': 'Zoom-Jwt-Request',
        'content-type': 'application/json'
    },
    json: true // Automatically parses the JSON string in the response
};

rp(options)
    .then(function (response) {
        console.log('User has', response);
    })
    .catch(function (err) {
        // API call failed...
        console.log('API call failed, reason ', err);
    });