Zoom SDK Web hide API key and Secret

I have tried using the Zoom SDK Web sample app

Just wondering how can i hide the API key and Secret. By following the instructions on this page, created a heroku app and it seems to be working when i make a POST request from postman.

What don’t know is how to get the signature to my front end app make it work with out keeping api secret and key in my index.js file.

I’m using CDN version. Live version hosted on here

my index.js file,

(function(){

    console.log('checkSystemRequirements');

    console.log(JSON.stringify(ZoomMtg.checkSystemRequirements()));

    // it's option if you want to change the WebSDK dependency link resources. setZoomJSLib must be run at first

    // if (!china) ZoomMtg.setZoomJSLib('https://source.zoom.us/1.7.2/lib', '/av'); // CDN version default

    // else ZoomMtg.setZoomJSLib('https://jssdk.zoomus.cn/1.7.2/lib', '/av'); // china cdn option 

    // ZoomMtg.setZoomJSLib('http://localhost:9999/node_modules/@zoomus/websdk/dist/lib', '/av'); // Local version default, Angular Project change to use cdn version

    ZoomMtg.preLoadWasm();

    ZoomMtg.prepareJssdk();
  
    var API_KEY = 'api_key'; 

    var API_SECRET = 'secret';

    document.getElementById('join_meeting').addEventListener('click', function(e){

        e.preventDefault();

        if(!this.form.checkValidity()){

            alert("Enter Name and Meeting Number");

            return false;

        }

        var meetConfig = {

            apiKey: API_KEY,

            apiSecret: API_SECRET,

            meetingNumber: parseInt(document.getElementById('meeting_number').value),

            userName: document.getElementById('display_name').value,

            passWord: "",

            leaveUrl: "https://zoom.us",

            role: 0

        };

        var signature = ZoomMtg.generateSignature({

            meetingNumber: meetConfig.meetingNumber,

            apiKey: meetConfig.apiKey,

            apiSecret: meetConfig.apiSecret,

            role: meetConfig.role,

            success: function(res){

                console.log(res.result);

            }

        });

        ZoomMtg.init({

            leaveUrl: 'http://www.zoom.us',

            isSupportAV: true,

            success: function () {

                ZoomMtg.join(

                    {

signature: signature,                        

meetingNumber: meetConfig.meetingNumber,

                        userName: meetConfig.userName,

                        signature: signature,

                        apiKey: meetConfig.apiKey,

                        userEmail: 'email@gmail.com',

                        passWord: meetConfig.passWord,

                        success: function(res){

                            $('#nav-tool').hide();

                            console.log('join meeting success');

                        },

                        error: function(res) {

                            console.log(res);

                        }

                    }

                );

            },

            error: function(res) {

                console.log(res);

            }

        });

    });

})();

Any help much appreciated. !

Thanks !Preformatted text

1 Like

I have developed this.

  1. In the html page, request the background to obtain a signature through the post method.
  2. In the background, obtain the signature through JAVA or PHP;
  3. Return the signature to the front desk.
    Can refer to:
    https://marketplace.zoom.us/docs/sdk/native-sdks/web/essential/signature
1 Like

Thank you very much for the suggestion. This is my index.js code now.

(function(){
	console.log('checkSystemRequirements');
	console.log(JSON.stringify(ZoomMtg.checkSystemRequirements()));

 ZoomMtg.setZoomJSLib('https://dmogdx0jrul3u.cloudfront.net/1.4.2/lib', '/av');

ZoomMtg.preLoadWasm();

ZoomMtg.prepareJssdk();

var API_KEY = 'xxxxxxxx';  

document.getElementById('join_meeting').addEventListener('click', function(e){
    e.preventDefault();

    if(!this.form.checkValidity()){
        alert("Enter Name and Meeting Number");
        return false;
    }

    var meetConfig = {
        apiKey: API_KEY,
        meetingNumber: parseInt(document.getElementById('meeting_number').value),
        userName: document.getElementById('display_name').value,
        passWord: "",
        leaveUrl: "https://zoom.us",
        role: 0
    };

    var endpoint = 'https://ipaa.herokuapp.com';
    fetch(`${endpoint}`, {
        method: 'POST',
        body: JSON.stringify({ meetingData: meetConfig })
    })
 
.then(result => result.text())
.then(response => {
    console.log(response);
        ZoomMtg.init({
        leaveUrl: 'http://www.zoom.us',
        isSupportAV: true,
        success: function () {
            ZoomMtg.join(
                {
                    signature: response,               
                    meetingNumber: meetConfig.meetingNumber,
                    userName: meetConfig.userName,
                    apiKey: meetConfig.apiKey,
                    //userEmail: 'user@gmail.com',
                    passWord: meetConfig.passWord,
                    success: function(res){
                        $('#nav-tool').hide();
                        console.log('join meeting success');
                    },
                    error: function(res) {
                        console.log(res);
                    }
                }
            );
        },
        error: function(res) {
            console.log(res);
        }
    });

})


});

})();

Im getting the following error “Join fail” .

**{method: "join", status: false, errorCode: 1, errorMessage: "joining fail", result: null}**

In the console i can see im getting a signature from my endpoint . But i notice that the length of signature received when i use heroku endpoint and using api key and secret directly on index.js page is different. (I have use the same meeting id to check both methods)

Is the issue here my endpoint not working properly and its wending the incorrect signature or is there any coding issue in my index.js file.

Thank you !

If the signature is generated according to the official method, there should be no problem.
Can you copy the signature generation method?

Im using Sample signature app referenced in the documentation. I have it deployed to heroku and using the app URL as my signature endpoint.

Then i pass my endpoint url as below to my index.js script.(documentation link)

var endpoint = 'https://ipaa.herokuapp.com';
    fetch(`${endpoint}`, {
        method: 'POST',
        body: JSON.stringify({ meetingData: meetConfig })
    })
 
.then(result => result.text())
.then(response => {
    console.log(response);
        ZoomMtg.init({
        leaveUrl: 'http://www.zoom.us',
        isSupportAV: true,
        success: function () {
            ZoomMtg.join(
                {
                    signature: response,               
                    meetingNumber: meetConfig.meetingNumber,
                    userName: meetConfig.userName,
                    apiKey: meetConfig.apiKey,
                    //userEmail: 'user@gmail.com',
                    passWord: meetConfig.passWord,
                    success: function(res){
                        $('#nav-tool').hide();
                        console.log('join meeting success');
                    },
                    error: function(res) {
                        console.log(res);
                    }
                }
            );

The JSON format returned from my visit to your URL address is shown below, but I don’t see the parsing of this JSON object in your code, and the corresponding fields are used for correct assignment. Please check.
{
“signature”: “QlN0cjUtRHJTYm1OQ1FoT2pWdGNEZy51bmRlZmluZWQuMTU4NTUyNDkxOTM4Ny51bmRlZmluZWQuZG12N3NPSGFiaW5CSUYzczlETXRCSFk0c01pcHdoTjh1TTUvUjd4a3BlZz0=”
}

console.log(response);
ZoomMtg.init({
leaveUrl: ‘http://www.zoom.us’,
isSupportAV: true,
success: function () {
ZoomMtg.join(
{
signature: response,

1 Like

I’m having the same problem as @charitha.
I can join a meeting successfully when using ZoomMtg.generateSignature() but I am getting an error when trying to use the Heroku app (https://marketplace.zoom.us/docs/sdk/native-sdks/web/essential/signature)

I’ve deployed it and entered my API key and secret – the same ones I’m using for the built-in generateSignature() function.

The error I’m getting doesn’t specify anything, unfortunately. It just says:
errorCode:1
errorMessage:“joining fail”
method:“join”
result:null
status:false

To check, I am comparing the signatures generated by the card-coded one and the heroku app and they start similarly but are different and also a different length.

For example:
ZoomMtg.generateSignature() returns:
bU5fQlZ0VHNSTzZTNFhpS2pKQzBUdy4yMDYyMzgwNTA1LjE1ODU1MzMyMzIxNzMuMC4yaVhEaklCZkRJejJ2WXd0WHdYMkllV1VrUm9ETzhDTi81MEs4OFY4ZjZzPQ
(126 characters long)

The Zoom Heroku app returns:
bU5fQlZ0VHNSTzZTNFhpS2pKQzBUdy51bmRlZmluZWQuMTU4NTUzMzI0ODg4OS51bmRlZmluZWQuaFhmQVBEVjJhSjEwSHVvbkE5eWR1bXNDRDJDSDVUdVRlS09Ec1FCK1FZND0=
(136 characters long)

At this point my two best guesses are

  1. that there is some difference in the way that ‘crypto’ and ‘crypto-js’ do their hashing or
  2. that there’s some problem being caused by web string encoding or something like that.

Would love some help!

Hi @drunkbiblestudy,

We just updated our sample generate signature app for node.js[1]. Can you re-clone the repo and see if generating a signature and joining a meeting works for you now?

1 - https://github.com/zoom/websdk-sample-signature-node.js

Thanks

Thanks @Michael_Purnell,
I will look into this more tomorrow. I see that you changed the Date().getTime() to include -30000 so it matches the other documentation.
From my immediate test, though, it seems to have the same problem where the keys returned are different lengths.
The built-in generateKey returns a 126 character string:
eg.
bU5fQlZ0VHNSTzZTNFhpS2pKQzBUdy4yMDYyMzgwNTA1LjE1ODU1NTM5NTMzODEuMC4yeU0wVVVaeWJOS1cyT1A2dlgrVFRVYjNQSWRYU0U2YUVsWm1pMUkwbUMwPQ

The heroku app returns a 136 character string.
I’ve tested with both AJAX and Fetch calls to see if that makes a difference but both returned 136 character strings. (both ending in 0=so maybe that’s significant).
eg.
bU5fQlZ0VHNSTzZTNFhpS2pKQzBUdy51bmRlZmluZWQuMTU4NTU1MzkzMjEzMC51bmRlZmluZWQuR3NIclhYVmIwNHMvQWhVNWhpSlZvQTFEaS9RQ0xjLzhNWnRqczZmMHdHVT0=
or
bU5fQlZ0VHNSTzZTNFhpS2pKQzBUdy51bmRlZmluZWQuMTU4NTU1MzkzMjEzMy51bmRlZmluZWQuRW9vOGFkYjU4dnRwS0pZNzlsczdCZDZIVWVGaU0remdjYVNTa1N4Z3VNbz0=

@Michael_Purnell
I’m still having the same problem.
Does anyone have an idea why the heroku app would return a different length of string from the built-in ZoomMtg.generateSignature function?

Hey @drunkbiblestudy,

After base64 decoding your signatures, you are passing in undefined for the meeting ID and the role.

That is probably the issue.

Thanks,
Tommy

Thanks for your help @zhang_meifu! :slight_smile:

@charitha, please let us know if you were able to resolve the issue.

Thanks,
Tommy

Hi @tommy and @zhang_meifu

Thanks for pointing us for the right direction.

My first mistake was sending this POST request to the endpoint in text format It should be JSON request. :innocent:

Secondly, as @zhang_meifu mentioned in his reply, i had few issue with my index.js too. The issue was, reply from my javascript fetch request did not correctly passed to the ZoomMtg.join function. About hour of trial and error, i was able to fix my code finally.

Happy to say its working well now. Below is my index.js file. :slightly_smiling_face:

(function(){

    console.log('checkSystemRequirements');

    console.log(JSON.stringify(ZoomMtg.checkSystemRequirements()));

 ZoomMtg.setZoomJSLib('https://dmogdx0jrul3u.cloudfront.net/1.4.2/lib', '/av');

ZoomMtg.preLoadWasm();

ZoomMtg.prepareJssdk();

var API_KEY = 'XXXXXXX';  

document.getElementById('join_meeting').addEventListener('click', function(e){

    e.preventDefault();

    if(!this.form.checkValidity()){

        alert("Enter Name and Meeting Number");

        return false;

    }

    var meetConfig = {

        apiKey: API_KEY,

        meetingNumber: parseInt(document.getElementById('meeting_number').value),

        userName: document.getElementById('display_name').value,

        passWord: "",

        leaveUrl: "https://zoom.us",

        role: 0

    };

    var endpoint = 'https://ipaa.herokuapp.com';

   var raw = JSON.stringify({"meetingNumber":meetConfig.meetingNumber,"role":1});

    fetch(`${endpoint}`, {

        method: 'POST',

        headers: {

            'Content-Type': 'application/json',

          },

        body: raw,

    })

.then(result => result.text())

.then(response => {

    console.log(response);

    var signature = JSON.parse(response);

    console.log(signature);

        ZoomMtg.init({

        leaveUrl: 'http://www.zoom.us',

        isSupportAV: true,

        success: function () {

            ZoomMtg.join(

                {

                    signature: signature.signature,               

                    meetingNumber: meetConfig.meetingNumber,

                    userName: meetConfig.userName,

                    apiKey: meetConfig.apiKey,

                    //userEmail: 'user@gmail.com',

                    passWord: meetConfig.passWord,

                    success: function(res){

                        $('#nav-tool').hide();

                        console.log('join meeting success');

                    },

                    error: function(res) {

                        console.log(res);

                    }

                }

            );

        },

        error: function(res) {

            console.log(res);

        }

    });

})

});

})();
1 Like

Hey @charitha,

Happy to hear it’s working now! :slight_smile:

Let us know if you have additional questions!

Thanks,
Tommy

Hi Tommy

It was working perfectly until now and im getting following error in console.

GET https://zoom.us/api/v1/wc/info?callback=localJsonpCallback&meetingNumber=6323493309&userName=Charitha&passWord=&signature=QlN0cjUtRHJXXXXXXXXXXXXXXXy41MzIzNDkzMzA5LjE1ODU5MDQ1MTk5MzQuMC5NT3BYd1FIVHV2TWJJZWQ1YnZwVlltMGFZUjRLU1RxRFM0MEFXVWlCd2o0PQ%3D%3D&apiKey=BStr5-DrSbmNCQhOjVtcDg&lang=en-US&userEmail=user%40gmail.com&cv=1.7.2&proxy=1&rwc=&_=1585904556002 net::ERR_ABORTED 403

Sample web app show the following error:- Your connection has timed out and you cannot join the meeting. Verify your network connectivity and try again.

Thanks !
Charitha

Hey @charitha,

We are working to get the Zoom Web Client and Zoom Web SDK back online. Please keep up with our status page for detailed updates: status.zoom.us


The best workaround is to use the Zoom Desktop / Mobile app.

Just include the Zoom meeting join url (https://zoom.us/j/meetingID) on your site rather than showing the websdk / iframe. Clicking on the join url will open the Zoom meeting in the Zoom app.

Apologies for the inconvenience,
Tommy

Please see the note from the Manager of Developer Relations at Zoom.

Thanks,
Tommy

Hi Tommy,

I’m still getting the same error. I have tried putting direct api key and secret according to sample app too. Still getting the same error.
error1

Thanks !

Charitha

Hey @charitha

Please see latest update here for the Web SDK:

https://marketplace.zoom.us/docs/guides/getting-started/stay-up-to-date/upcoming-changes/web-sdk

Thanks,
Tommy