We’re just migrating to the new Zoom library, which requires using the JWT instead of app-id and app-secret.
I’m getting the same error message: errorCode = 4, internalErrorCode=124.
This is the code how the JWT is generated using Scala with BouncyCastle.
override def createJwt(issuedAt: Instant, role: Int, meetingNumber: Long): String = {
val expiresAt = issuedAt.plus(3, HOURS)
val header = """{"typ":"JWT","alg":"HS256"}"""
val payload = s"""{"appKey":"$clientId","sdkKey":"$clientId","mn":$meetingNumber,"role":$role,"iat":${issuedAt.getEpochSecond},"exp":${expiresAt.getEpochSecond},"tokenExp":${expiresAt.getEpochSecond}}"""
val encodedHeaderAndPayload = java.util.Base64.getUrlEncoder.withoutPadding().encodeToString(header.getBytes) + "." + java.util.Base64.getUrlEncoder.withoutPadding().encodeToString(payload.getBytes)
val hmac = new HMac(new SHA256Digest())
hmac.init(new KeyParameter(clientSecret.getBytes("UTF-8")))
val result = new Array[Byte](hmac.getMacSize)
val bytes = encodedHeaderAndPayload.getBytes("UTF-8")
hmac.update(bytes, 0, bytes.length)
hmac.doFinal(result, 0);
return encodedHeaderAndPayload + "." + java.util.Base64.getUrlEncoder.withoutPadding().encodeToString(result)
}
Checking the JWT on jwt.io with the client-secret yields in a valid signature. Here is an example JWT signed with the client-secret the-very-long-and-secure-client-secret
:
Header:
{
"typ": "JWT",
"alg": "HS256"
}
Payload:
{
"appKey": "the-client-id",
"sdkKey": "the-client-id",
"mn": 123456,
"role": 0,
"iat": 1705665600,
"exp": 1705676400,
"tokenExp": 1705676400
}
JWT:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhcHBLZXkiOiJ0aGUtY2xpZW50LWlkIiwic2RrS2V5IjoidGhlLWNsaWVudC1pZCIsIm1uIjoxMjM0NTYsInJvbGUiOjAsImlhdCI6MTcwNTY2NTYwMCwiZXhwIjoxNzA1Njc2NDAwLCJ0b2tlbkV4cCI6MTcwNTY3NjQwMH0.RgKwpgwuySzJk2k0R-_sY_vK1zNJhmK-jksD5sciwnc
Are the datatypes for role and mn correct? They are not stated explicitly in the documentation, so I inferred them as numbers, not strings.
Any help is appreciated. @chunsiong.zoom