What is a JSON Web Token (JWT)?
A JWT (JSON Web Token) is an open standard (RFC 7519) for securely transmitting information between parties as a JSON object. The object could be encrypted and signed with a private/public key, and it is commonly used for authentication and authorization in web applications.
You can think of JWT as a digital ID card used in web applications to confirm who you are without logging in every time you interact with that application.
It is important to know how to generate a JWT token, as the Network APIs use them to perform authorization. There are several ways to generate a new JWT token when consuming Vonage APIs:
Using the JWT online generator. You’ll need your application ID and the private key generated by the application in your dashboard. Network APIs don’t require any extra ACL property.
Using the Vonage CLI tool. Similar to the online generator, a private key and an application ID must be provided: vonage jwt --key_file=path/to/private.key --app_id=<application_id>
If you are using one of our SDKs, you don’t have to worry about JWT because all SDKs support the generation of JWT tokens.
What if I want to generate the JWT tokens without depending on any external tool or library? If that’s the case, keep reading!
JWT Structure
Before implementing JWT, it’s important to understand its structure.
A JWT consists of the header, payload, and signature. These parts are encoded separately using the Base64url encoding algorithm and concatenated using periods:
jwt = base64url(header) + '.' + base64url(payload) + '.' + base64url(signature)
Let’s dive in!
Header
Specifies which algorithm is used to generate the signature. For Vonage APIs, the header will look like this:
{
alg: "RS256",
typ: "JWT"
};
Payload
It includes information about the user and their claims, such as the application ID, issued time, expiration time, etc. The following list contains the required keys when using Vonage APIs:
application_id. Corresponds to the ID of the application with Network Registry capabilities, created in the user’s dashboard.
iat. The time at which the token was issued.
nbf. The time at which the token should become valid.
exp. The time at which the token should expire.
acl. A list of permissions that this token will have. For Network APIs, we’ll use an empty value as the APIs don’t need any extra permissions.
jti. A unique identifier for the JWT.
Signature
It works as a stamp to validate the token. It is calculated by encoding the header and payload using the Base64url encoding algorithm, and signed using a secret key. The public and secret keys can be found within the application settings in the user’s dashboard.
How to Generate a JWT in JavaScript
The first step would be to create the header:
const header = { alg: "HS256", // Hashing algorithm
typ: "JWT"
};
Next, create the payload. In this example, we set an expiration time of one hour:
const currentTime = Math.floor(Date.now() / 1000);
const payload = { application_id: 123-456-789,
iat: currentTime,
nbf: currentTime,
exp: currentTime + (60 * 60),
acl : ‘’,
jti: Math.random()
};
The next step is to encode both the header and the payload:
const encodedHeader = base64url(JSON.stringify(header));
const encodedPayload = base64url(JSON.stringify(payload));
JavaScript does not include an implementation of the Base64URL algorithm, so we must implement our own version:
function base64url(str) {
let encodedSource = Buffer.from(str).toString('base64');
// remove padding and replace characters
return encodedSource
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}
Next, let’s create the signature:
const crypto = require('crypto');
const secretKey = "your_secret_key";
const signature = crypto.createHmac('sha256', secretKey) .update(`${encodedHeader}.${encodedPayload}`)
.digest('base64url');
Finally, our JWT is ready to be used:
const jwt = `${encodedHeader}.${encodedPayload}.${signature}`;
console.log(jwt);
How to Generate a JWT in Python
The code to implement a JWT is very similar to the JavaScript version. Let’s start by implementing the Base64URL algorithm:
import base64
import hmac
import hashlib
import json
import time
def base64url(data):
encoded_data = base64.urlsafe_b64encode(data).rstrip(b'=')
return encoded_data.decode('utf-8')
Next, define our header and payload:
header = { "alg": "HS256", "typ": "JWT" }
payload = { "application_id": "123-456-789",
"iat": int(time.time()),
"nbf": int(time.time()),
"exp": int(time.time()) + 3600,
"acl": "",
"jti": random.random()
}
The next step is to encode both the header and the payload:
encoded_header = base64url(json.dumps(header).encode('utf-8'))
encoded_payload = base64url(json.dumps(payload).encode('utf-8'))
We are ready to create the signature:
secret_key = 'your_secret_key'
message = f'{encoded_header}.{encoded_payload}'
signature = hmac.new(secret_key.encode('utf-8'), message.encode('utf-8'), hashlib.sha256).digest()
encoded_signature = base64url(signature)
Our JWT is ready to be used:
jwt_token = f'{encoded_header}.{encoded_payload}.{encoded_signature}'
print(jwt_token)
How to Use JWT with Network APIs
The Network APIs use JWT during the authorization step before making any API call. Given that tokens are credentials, we should take into consideration some security measures to prevent security issues:
The generation of the JWT should be done on the backend side.
Do not keep tokens’ expiration time longer than required.
Once generated, users should be able to use the token to access protected endpoints. This is typically done using the Authorization header using the Bearer schema:
Authorization: Bearer <token>
The Network APIs authorization documentation contains a detailed description of how to use JWT tokens in front-end and back-end scenarios.
Get in Touch
Have you implemented JWT in your favorite language? We’d love to see your code! Join us on the Vonage Developer Community Slack or message us on X, and we will get back to you.
Thanks for reading!
Alvaro is a developer advocate at Vonage, focusing on Network APIs. Passionate about Developer Experience, APIs, and Open Source. Outside work, you can often find him exploring comic shops, attending sci-fi and horror festivals or crafting stuff with those renowned tiny plastic building blocks.