Skip to content

JSON Web Token (JWT) structure and generation example

Alexander Boldyrev edited this page Jun 27, 2025 · 1 revision

Required structure of JSON Web Token (JWT)

The JWT that was supplied to the Mobile Messaging SDK call is verified:

  • on server side when fetching the inbox for the person with external person id.
  • both before making the request and also on the server side when it is used for user data authorization

The required claims and headers for verification are listed in the following table:

Header / Claim Description
kid (Header) A standard header that identifies the ID of the secret key used to securely sign the token. The value of this header should be equal to the "secret key id" from the Infobip web interface. The details are explained in the following "Example" chapter.
typ (Claim) A non-standard claim which is still used by the software to verify the type of the token. Should always have "Bearer" value.
sub (Claim) A standard claim that identifies the person that this token was given to. The value of this header is verified to be equal to the external person id of the person, owning the requested Inbox.
infobip-api-key (Claim) A custom claim. The value of this header should be equal to the "Application Code" that can be retrieved from the App Profile configuration page
iat (Claim) A standard claim. This claim is mandatory for the supplied JWT.
exp (Claim) A standard claim. This claim is mandatory for the supplied JWT.
jti (Claim) A standard claim. This claim is mandatory for the supplied JWT.

Example

JWTs can be generated in multiple ways using different tools. Below are minimal code samples that show how to include the claims and headers verified by the Infobip system. Several parameters used in the following examples are described here:

  • The applicationCode parameter is located at the top of Application Profile configuration. It is visible and can be copied using the icon button:
Application code - copy action
  • The keyId and secretKeyHex parameters can be obtained by using the copy icon in the JWT private keys section of the App Profile page:
Secret key - copy action
  • The externalPersonId parameter uniquely identifies the person in CDP. This should be known by your backend before the token is generated.

Java Example

The Java example below uses the nimbus-jose-jwt dependency. Java 17 or later is required due to the use of the HexFormat class.

import com.nimbusds.jose.JOSEObjectType;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
 
import java.time.Instant;
import java.util.Date;
import java.util.HexFormat;
import java.util.UUID;
 
public class JwtComposer {
    public String generateSignedJwt(String keyId, String secretKeyHex, String applicationCode, String externalPersonId) throws Exception {
        // simple example how JWT issuing process could look like:
        MACSigner personalizationTokenSigner = new MACSigner(HexFormat.of().parseHex(secretKeyHex));
        JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
                .claim("typ", "Bearer")                                     // Mandatory. Type of the token
                .jwtID(UUID.randomUUID().toString())                        // Mandatory. Unique ID of this token
                .subject(externalPersonId)                                  // Mandatory. External Person Id identifying the person in CDP
                .issuer(applicationCode)                                    // Mandatory. Identifier of the issuer. Value is specific to the customer
                .issueTime(new Date())                                      // Mandatory. When this token was issued
                .expirationTime(Date.from(Instant.now().plusMillis(15000))) // Mandatory. When this token should be invalidated
                .claim("infobip-api-key", applicationCode)                  // Mandatory. Custom claim identifying the application, signing the JWT
                .build();
        JWSHeader jwsHeader = new JWSHeader.Builder(JWSAlgorithm.HS256).type(JOSEObjectType.JWT).keyID(keyId).build();
        SignedJWT personalizedToken = new SignedJWT(jwsHeader, claimsSet);
        personalizedToken.sign(personalizationTokenSigner);
        return personalizedToken.serialize();
    }
}

Node JS Example

Node JS example uses jsonwebtoken and uuid as dependencies. uuid dependency is used only to generate unique JWT ID.

const jwt = require('jsonwebtoken');
const uuid = require('uuid');
 
function generateSignedJWT(keyid, secretKeyHex, applicationCode, externalPersonId) {
    const timestamp = Math.floor(new Date().getTime()/1000);
    const payload = {
        typ: 'Bearer',                     // Mandatory. Type of the token
        jti: uuid.v4(),                    // Mandatory. Unique ID of this token
        sub: externalPersonId,             // Mandatory. External Person Id identifying the person in CDP
        iss: applicationCode,              // Mandatory. Identifier of the issuer. Value is specific to the customer
        iat: timestamp,                    // Mandatory. When this token was issued
        exp: timestamp + 15,               // Mandatory. When this token should be invalidated
        'infobip-api-key': applicationCode // Mandatory. Custom claim identifying the application, signing the JWT
    };
    return jwt.sign(payload, Buffer.from(secretKeyHex, 'hex'), { keyid });
}
Clone this wiki locally