OAuth not working (Urgent - Project due...) NodeJS

I have project due by 9th and one of its major module is Zoom integration…

I am trying to get access_token by passing the code while making a POST request using FETCH to https://zoom.us/oauth/token

Its just not working, i get error: Bad request error 401

Method 1:

app.post(“/connectZoom”, async(req,res) => {
try {
const b = Buffer.from(process.env.CLIENT_ID + “:” + process.env.CLIENT_SECRET);
const zoomRes = await fetch(https://zoom.us/oauth/token?grant_type=authorization_code&code=${req.body.code}&redirect_uri=${process.env.ZOOM_REDIRECT_URL}, {
method: “POST”,
headers: {
Authorization: Basic ${b.toString("base64")},
},
})
if(!zoomRes.ok)
console.log(‘Something went wrong.’);
console.log(zoomRes)
return res.status(401).send(“Could not connect with Zoom”);
} catch (e) {
console.log(e)
return res.status(500).send(“Something went wrong”);
}
})

Method 2:
app.post(“/connectZoomm”, async(req,res) => {
try {
console.log(req.body.code)
console.log(‘Here1’)
let basicAuth = Buffer.from(${process.env.CLIENT_ID}:${process.env.CLIENT_SECRET}).toString(“base64”);
console.log(basicAuth)
const zoomRes = await fetch(‘https://zoom.us/oauth/token’, {
method: “POST”,
headers: {
Authorization: Basic ${basicAuth},
‘Content-Type’: ‘application/x-www-form-urlencoded’
},
body:grant_type=authorization_code&code=${req.body.code}&redirect_uri=${process.env.ZOOM_REDIRECT_URL}
});
console.log(‘Here2’)
console.log(zoomRes)
if(!zoomRes.ok)
console.log(“Here Error”)
return res.status(401).send(“Could not connect with Zoom”);
} catch (e) {
console.log(e)
return res.status(500).send(“Something went wrong”);
}
})

I am now going to try doing this using Axios instead of Fetch and see if it works. It works using postman though. I am really frustrated atm, anxiety going through the roof.

@freelancer.nak kindly help if you can would be highly appreciated.

Here is the working code

First, you need to import :point_down:

const axios = require('axios');
const qs = require('qs');
 var data = qs.stringify({
        code: code,
        grant_type: 'authorization_code',
        redirect_uri: process.env.ZOOM_OAUTH_REDIRECT_URI
    });

    var config = {
        method: 'post',
        url: 'https://zoom.us/oauth/token',
        headers: {
            "Content-Type": "application/x-www-form-urlencoded",
            "Authorization": "Basic " + Buffer.from(`${process.env.ZOOM_CLIENT_ID}:${process.env.ZOOM_CLIENT_SECRET}`).toString('base64')
        },
        data: data
    };

    var result = await axios(config)
        .then(function (response) {
            return response;
        })
        .catch(function (error) {
            return error;
        });

Any queries still please share. Welcome & Thanks

Still getting an error: AxiosError: Request failed with status code 400
at settle (C:\Users\Administrator\Documents\Zoom2\backend\node_modules\axios\dist\node\axios.cjs:1859:12)
at IncomingMessage.handleStreamEnd (C:\Users\Administrator\Documents\Zoom2\backend\node_modules\axios\dist\node\axios.cjs:2723:11)
at IncomingMessage.emit (node:events:525:35)
at endReadableNT (node:internal/streams/readable:1359:12)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
code: ‘ERR_BAD_REQUEST’,

@i190573 Please remove node_modules and re install and try.

Still not working.

Code:
app.post(“/connectZoomm”, async(req,res) => {
try {
console.log(req.body.code)
console.log(‘Here1’)
var data = qs.stringify({
code: req.body.code,
grant_type: ‘authorization_code’,
redirect_uri: process.env.ZOOM_REDIRECT_URL
});

var config = {
    method: 'post',
    url: 'https://zoom.us/oauth/token',
    headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        "Authorization": "Basic " + Buffer.from(`${process.env.ZOOM_CLIENT_ID}:${process.env.ZOOM_CLIENT_SECRET}`).toString('base64')
    },
    data: data
};

var zoomRes = await axios(config)
    .then(function (response) {
        return response;
    })
    .catch(function (error) {
        return error;
    });
console.log('Here2')
console.log(zoomRes)
if(!zoomRes.ok)
  console.log("Here Error")
  return res.status(401).send("Could not connect with Zoom");
const zoomData = await zoomRes.json();
console.log('Here3')
if (zoomData.error)
  return res.status(401).send("Could not connect with Zoom");
// Retreive user details
console.log('Here3')
const zoomUserRes = await fetch("https://api.zoom.us/v2/users/me", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${zoomData.access_token}`,
  },
});
console.log('Here4')
const zoomUserData = await zoomUserRes.json();
/* 
  Encrypt and store below details to your database:
    zoomUserData.email
    zoomUserData.account_id
    zoomData.access_token
    zoomData.refresh_token
    zoomData.expires_in // convert it to time by adding these seconds to current time
*/
return res.send({
  /* Return necessary data to frontend */
});

} catch (e) {
console.log(e)
return res.status(500).send(“Something went wrong”);
}
})

Error:

Zoom Backend started on port 4000!
wEmHIQgpEfpF7rRPqjeQpmR_Lu89dlsWw
Here1
Here2
AxiosError: Request failed with status code 400
at settle (C:\Users\Administrator\Documents\Zoom2\backend\node_modules\axios\dist\node\axios.cjs:1859:12)
at IncomingMessage.handleStreamEnd (C:\Users\Administrator\Documents\Zoom2\backend\node_modules\axios\dist\node\axios.cjs:2723:11)
at IncomingMessage.emit (node:events:525:35)
at endReadableNT (node:internal/streams/readable:1359:12)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
code: ‘ERR_BAD_REQUEST’,
config: {
transitional: {
silentJSONParsing: true,
forcedJSONParsing: true,
clarifyTimeoutError: false
},
adapter: [ ‘xhr’, ‘http’ ],
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
xsrfCookieName: ‘XSRF-TOKEN’,
xsrfHeaderName: ‘X-XSRF-TOKEN’,
maxContentLength: -1,
maxBodyLength: -1,
env: { FormData: [Function], Blob: [class Blob] },
validateStatus: [Function: validateStatus],
headers: AxiosHeaders {
Accept: ‘application/json, text/plain, /’,
‘Content-Type’: ‘application/x-www-form-urlencoded’,
Authorization: ‘Basic dW5kZWZpbmVkOnVuZGVmaW5lZA==’,
‘User-Agent’: ‘axios/1.2.2’,
‘Content-Length’: ‘112’,
‘Accept-Encoding’: ‘gzip, compress, deflate, br’
},
method: ‘post’,
url: ‘https://zoom.us/oauth/token’,
data: ‘code=wEmHIQgpEfpF7rRPqjeQpmR_Lu89dlsWw&grant_type=authorization_code&redirect_uri=https%3A%2F%2Flocalhost%3A3000’
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype] {
abort: [Function (anonymous)],
aborted: [Function (anonymous)],
connect: [Function (anonymous)],
error: [Function (anonymous)],
socket: [Function (anonymous)],
timeout: [Function (anonymous)],
finish: [Function: requestOnFinish]
},
_eventsCount: 7,
_maxListeners: undefined,
outputData: ,
outputSize: 0,
writable: true,
destroyed: true,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: true,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
strictContentLength: false,
_contentLength: ‘112’,
_hasBody: true,
_trailer: ‘’,
finished: true,
_headerSent: true,
_closed: true,
socket: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
secureConnecting: false,
_SNICallback: null,
servername: ‘zoom.us’,
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 9,
connecting: false,
_hadError: false,
_parent: null,
_host: ‘zoom.us’,
_closeAfterHandlingError: false,
_readableState: [ReadableState],
_maxListeners: undefined,
_writableState: [WritableState],
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: ‘’,
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
timeout: 5000,
parser: null,
_httpMessage: null,
[Symbol(res)]: [TLSWrap],
[Symbol(verified)]: true,
[Symbol(pendingSession)]: null,
[Symbol(async_id_symbol)]: -1,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: Timeout {
_idleTimeout: 5000,
_idlePrev: [TimersList],
_idleNext: [TimersList],
_idleStart: 39710,
_onTimeout: [Function: bound ],
_timerArgs: undefined,
_repeat: null,
_destroyed: false,
[Symbol(refed)]: false,
[Symbol(kHasPrimitive)]: false,
[Symbol(asyncId)]: 49,
[Symbol(triggerId)]: 47
},
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kSetNoDelay)]: false,
[Symbol(kSetKeepAlive)]: true,
[Symbol(kSetKeepAliveInitialDelay)]: 1,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object]
},
_header: ‘POST /oauth/token HTTP/1.1\r\n’ +
‘Accept: application/json, text/plain, /\r\n’ +
‘Content-Type: application/x-www-form-urlencoded\r\n’ +
‘Authorization: Basic dW5kZWZpbmVkOnVuZGVmaW5lZA==\r\n’ +
‘User-Agent: axios/1.2.2\r\n’ +
‘Content-Length: 112\r\n’ +
‘Accept-Encoding: gzip, compress, deflate, br\r\n’ +
‘Host: zoom.us\r\n’ +
‘Connection: keep-alive\r\n’ +
‘\r\n’,
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: Agent {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
defaultPort: 443,
protocol: ‘https:’,
options: [Object: null prototype],
requests: [Object: null prototype] {},
sockets: [Object: null prototype] {},
freeSockets: [Object: null prototype],
keepAliveMsecs: 1000,
keepAlive: true,
maxSockets: Infinity,
maxFreeSockets: 256,
scheduling: ‘lifo’,
maxTotalSockets: Infinity,
totalSocketCount: 1,
maxCachedSessions: 100,
_sessionCache: [Object],
[Symbol(kCapture)]: false
},
socketPath: undefined,
method: ‘POST’,
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: ‘/oauth/token’,
_ended: true,
res: IncomingMessage {
_readableState: [ReadableState],
_events: [Object: null prototype],
_eventsCount: 4,
_maxListeners: undefined,
socket: null,
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: ‘1.1’,
complete: true,
rawHeaders: [Array],
rawTrailers: ,
aborted: false,
upgrade: false,
url: ‘’,
method: null,
statusCode: 400,
statusMessage: ‘Bad Request’,
client: [TLSSocket],
_consuming: true,
_dumped: false,
req: [Circular *1],
responseUrl: ‘https://zoom.us/oauth/token’,
redirects: ,
[Symbol(kCapture)]: false,
[Symbol(kHeaders)]: [Object],
[Symbol(kHeadersCount)]: 54,
[Symbol(kTrailers)]: null,
[Symbol(kTrailersCount)]: 0
},
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: ‘zoom.us’,
protocol: ‘https:’,
_redirectable: Writable {
_writableState: [WritableState],
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
_options: [Object],
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: ,
_requestBodyLength: 112,
_requestBodyBuffers: ,
_onNativeResponse: [Function (anonymous)],
_currentRequest: [Circular 1],
_currentUrl: ‘https://zoom.us/oauth/token’,
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kBytesWritten)]: 0,
[Symbol(kEndCalled)]: true,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [Array],
‘content-type’: [Array],
authorization: [Array],
‘user-agent’: [Array],
‘content-length’: [Array],
‘accept-encoding’: [Array],
host: [Array]
},
[Symbol(errored)]: null,
[Symbol(kUniqueHeaders)]: null
},
response: {
status: 400,
statusText: ‘Bad Request’,
headers: AxiosHeaders {
date: ‘Sat, 07 Jan 2023 10:54:53 GMT’,
‘content-type’: ‘application/json;charset=UTF-8’,
‘transfer-encoding’: ‘chunked’,
connection: ‘keep-alive’,
‘x-zm-trackingid’: ‘v=2.0;clid=us04;rid=WEB_72cc2ae3b84af366d761db7c48aa4a17’,
‘x-content-type-options’: ‘nosniff’,
‘content-security-policy’: "upgrade-insecure-requests; default-src https://
.zoom.us https://zoom.us blob: ‘self’; img-src https: about: blob: data: ‘self’; style-src https: safari-extension: chrome-extension:
‘unsafe-inline’ data: ‘self’; font-src https: safari-extension: chrome-extension: blob: data: ‘self’; connect-src * about: blob: data: ‘self’; media-src * rtmp: blob: data: ‘self’; frame-src https: ms-appx-web: zoommtg: zoomus: wvjbscheme: data: ‘self’; object-src ‘none’; base-uri ‘none’;",
‘x-frame-options’: ‘SAMEORIGIN’,
‘set-cookie’: [Array],
‘x-zm-zoneid’: ‘VA’,
‘cache-control’: ‘no-store’,
pragma: ‘no-cache’,
‘cf-cache-status’: ‘DYNAMIC’,
‘report-to’: ‘{“endpoints”:[{“url”:“https:\/\/a.nel.cloudflare.com\/report\/v3?s=x3Sa7deXCSYV6sS5fpPgHQJ%2Bj2BeM5I3YVVuxRdRcF4UAgsK1MSqcvAPNOdWsBae6ZQtmOeSb4vOE9XtEcPvpzNGH3jd2QV62SnPFxdZS63yx8caEtj4zRA%3D”}],“group”:“cf-nel”,“max_age”:604800}’,
nel: ‘{“success_fraction”:0.01,“report_to”:“cf-nel”,“max_age”:604800}’,
server: ‘cloudflare’,
‘cf-ray’: ‘785c286c68cb4c03-SIN’
},
config: {
transitional: [Object],
adapter: [Array],
transformRequest: [Array],
transformResponse: [Array],
timeout: 0,
xsrfCookieName: ‘XSRF-TOKEN’,
xsrfHeaderName: ‘X-XSRF-TOKEN’,
maxContentLength: -1,
maxBodyLength: -1,
env: [Object],
validateStatus: [Function: validateStatus],
headers: [AxiosHeaders],
method: ‘post’,
url: ‘https://zoom.us/oauth/token’,
data: ‘code=wEmHIQgpEfpF7rRPqjeQpmR_Lu89dlsWw&grant_type=authorization_code&redirect_uri=https%3A%2F%2Flocalhost%3A3000’
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
outputData: ,
outputSize: 0,
writable: true,
destroyed: true,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: true,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
strictContentLength: false,
_contentLength: ‘112’,
_hasBody: true,
_trailer: ‘’,
finished: true,
_headerSent: true,
_closed: true,
socket: [TLSSocket],
_header: ‘POST /oauth/token HTTP/1.1\r\n’ +
‘Accept: application/json, text/plain, /\r\n’ +
‘Content-Type: application/x-www-form-urlencoded\r\n’ +
‘Authorization: Basic dW5kZWZpbmVkOnVuZGVmaW5lZA==\r\n’ +
‘User-Agent: axios/1.2.2\r\n’ +
‘Content-Length: 112\r\n’ +
‘Accept-Encoding: gzip, compress, deflate, br\r\n’ +
‘Host: zoom.us\r\n’ +
‘Connection: keep-alive\r\n’ +
‘\r\n’,
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: [Agent],
socketPath: undefined,
method: ‘POST’,
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: ‘/oauth/token’,
_ended: true,
res: [IncomingMessage],
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: ‘zoom.us’,
protocol: ‘https:’,
_redirectable: [Writable],
[Symbol(kCapture)]: false,
[Symbol(kBytesWritten)]: 0,
[Symbol(kEndCalled)]: true,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype],
[Symbol(errored)]: null,
[Symbol(kUniqueHeaders)]: null
},
data: {
reason: ‘Invalid client_id or client_secret’,
error: ‘invalid_client’
}
}
}
Here Error

Error on Browser:

What you are trying to achieve using OAuth flow?

Thank you, its all working now.

1 Like

@i190573 Great. Welcome & Thanks