Can't create meeting by using an access token(client_credentials) for server-to-server oauth type

Dears,
Hope to get your help.

API Endpoint(s) and/or Zoom API Event(s)
https://api.zoom.us/v2/users/{my-user-id}/meetings

Description
I’m trying to create meeting by using Zoom meeting Apis
After getting an access token by using grant type of client_credentials and using client id and client secret of server-to-server oauth app type. By this way I got an access token
“But when trying to use this access token at create meeting api I got the error message the mentioned below”

Error?
Invalid api key or secret.

How To Reproduce
Steps to reproduce the behavior:
1. https://api.zoom.us/v2/users/{my-user-id}/meetings
2. client credentials and server to server oauth app type
3. {
“code”: 200,
“message”: “Invalid api key or secret.”
}

Hi @xpe

Hope you are doing great! I am happy to help here!
This looks like a credentials issue.
Please refer to the following thread were I helped other developers with a similar issue:

Hope this helps :slight_smile:
Elisa

Hi @elisa.zoom ,

I did made the required changes mentioned above to the owner role, However, still facing the same issue.

Zoom Issue2

Thank you.

Hi @xpe,
Interesting.
It might be the way you are making the request then.
Feel free to refer to this post and let me know if it helps:

1 Like

Hi @elisa.zoom ,

Thanks for your help, that URL fixes my issue.
But I have another issue when trying to join meeting through Meeting Web SDK, Using sdk jwt type.
After generating SDK JWT token as a signature(by using SDK key and SDK secret that generated from SDK type app ) and pass this signature to join meeting function with the other parameters, I got this error( errorCode: 3712, errorMessage: “Signature is invalid.”, method: “join”, result: “Invalid signature.”, status: false ).

1 Like

@xpe ,

Have you tried to generate the signature with our sample? I’ve found manually entering the output from our sample app, then comparing signatures helps isloate the root cause.

Thanks for chiming in @donte.zoom
I appreciate your help!

1 Like

Hello again,
I can confirm from the sample above that I have something wrong in my signature. But I really cannot figure it out.

This signature is generated with my code:

[REDACTED]

And this one is generated with the sample:

[REDACTED]

both signatures are for the same meeting number.

The generated tokens are so close even in time but the one from the sample is working and the one generated with my app is not working and getting me Invalid Signature error!

I don’t know where the problem is.
I’m using C# and JwtSecurityTokenHandler

and creating the token as follows:

meetingNumber = "xxxxxxxxxx";

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new[]
                {   
                    new Claim("sdkKey", sdkKey),
                    new Claim("mn", meetingNumber),
                    new Claim("role", role),
                    new Claim("iat", ts.ToString()),
                    new Claim("exp", expTs.ToString()),
                    new Claim("appKey", sdkKey),
                    new Claim("tokenExp", expTs.ToString())
                }),

                //Expires = now.AddMinutes(Convert.ToInt32(120)),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(symmetricKey),SecurityAlgorithms.HmacSha256Signature)
            };

            var stoken = tokenHandler.CreateToken(tokenDescriptor);

Appreciate if you can help.
Thanks and regards

@xpe ,
It looks like the iat value is invalid. You can use https://jwt.io/ to decode your token and verify the values for the payload properties are correct:

For reference, here is our help documentation generating an SDK JWT token:

Also, please do not post your token on the Forum as it is considered PII.

Hello Donte.Zoom,

Thanks for your replay.
The invalid date is appearing just because of the double quotes. Actually, the value you are referring to, is in the working signature.
I tried by both, the double quotes and without but the result is the same.

Thanks

After investigation, I can confirm that the problem is in the way I’m using the signature.
I’m revising it. appreciate if there is any updated code that is in c# or .Net for SDK signature generation.

1 Like

I was able to find the solution for the problem.
I was treating apiSecret as base64 string and converting it to byte using:
var symmetricKey = Convert.FromBase64String(apiSecret);

And this was the issue.
Using ASCII encoding instead solved the problem:
var symmetricKey = Encoding.ASCII.GetBytes(apiSecret);

Thanks for your time and support.

1 Like

Awesome to hear you were able to resolve the issue, @xpe! I will make sure to get this caveat documented and will share it here. In the meantime, can you share the entire code snippet of the working solution for other community members’ benefit?

Here is a complete signature generation code using c# and System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler
hopefully it would help others:


public string GenerateSdkJwtToken(string apiKey, string apiSecret, string meetingNumber, int role)
        { 
            //convert secret to byte[]. This is the correct way.
            var symmetricKey = Encoding.ASCII.GetBytes(apiSecret);
            var tokenHandler = new JwtSecurityTokenHandler();
            //don't automatically add nbf to the generated token.
            tokenHandler.SetDefaultTimesOnTokenCreation = false;
            //set issue date and expiration.
            var now = DateTime.UtcNow;
            //get epoch seconds.
            long tss = ToTimestamp(now.ToUniversalTime()) - 30;
            long expTs = tss + 60 * 60 * 2; //add a reasonable value for expiration time.
            //token payload
            var objTokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new[]
                {   
                    new Claim("sdkKey", sdkKey),
                    new Claim("mn", meetingNumber),
                    new Claim("role", role.ToString()),
                    new Claim("iat", tss.ToString()),
                    new Claim("exp", expTs.ToString()),
                    new Claim("appKey", sdkKey),
                    new Claim("tokenExp", expTs.ToString())
                }),
                //sign the token using Sha256
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(symmetricKey),SecurityAlgorithms.HmacSha256Signature)
            };

            var sTokenObj = tokenHandler.CreateToken(objTokenDescriptor );
            var strJwtToken = tokenHandler.WriteToken(sTokenObj);
            //here is your final token.
            return strJwtToken;
        }
//There are several way you can get Epoch seconds. Here is one method 
public static long ToTimestamp(DateTime value)
        {
            TimeSpan t = value - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            long secondsSinceEpoch = (int)t.TotalSeconds;
            return secondsSinceEpoch;
        }
1 Like

Awesome, @xpe! Thank you so much for sharing your solution with the community. It will be greatly beneficial to others encountering the same issue.