JSON Web Tokens

Creating a JSON Web Token:

OBJECT jwt := NEW JSONWebToken("ES256", BlobToString(GetDiskResource("/path/to/pem-encoded-ecdsa-key")));
jwt->payload :=
    [ iat := GetCurrentDateTime()
    , exp := AddDaysToDate(1, GetCurrentDateTime())
    ];
STRING authvalue := jwt->GetAuthorizationValue();

If you're using claim names with uppercase characters, you can use JSONWebToken::SetPayload to supply JSON translations:

OBJECT jwt := NEW JSONWebToken("ES256", BlobToString(GetDiskResource("/path/to/pem-encoded-ecdsa-key")));
jwt->SetPayload(
    [ iat := GetCurrentDateTime()
    , exp := AddDaysToDate(1, GetCurrentDateTime())
    , loggedInAs := "admin"
    ], CELL[ "loggedInAs" ]);
STRING authvalue := jwt->GetAuthorizationValue();

A JSON Web Token is self-contained, so to verify it, the secret or public key to use has to be determined by the contents of the JWT itself. To verify a JWT, use the secret_callback option to return the secret or public key to use for verification.

// Get the authorization value from the Authorization HTTP header
STRING authvalue := GetWebHeader("Authorization");
IF (authvalue NOT LIKE "Bearer *")
  THROW NEW Exception("Expected Bearer");
authvalue := Substring(authvalue, 7);

// Verify the authorization value, which returns a verify-only JWT or throws in case of an error
OBJECT jwt;
TRY
{
  jwt := VerifyJSONWebToken(authvalue, [ alg := [ "ES256" ], secret_callback := PTR GetPublicKey ]);
}
CATCH (OBJECT e)
{
  AbortWithHTTPError(403, "JWT verification failed");
}
RECORD payload := jwt->GetPayload(STRING[ "loggedInAs" ]);

STRING FUNCTION GetPublicKey(STRING header_kid)
{
  // Retrieve the public key by the key ID in the JWT header
  RETURN SELECT AS STRING public_key FROM userdatabase WHERE key_id = header_kid;
}