Zoom OAuth with NEXT.js App

I am a full-stack web developer that enjoys coding in Laravel and React.
Search for a command to run...

I am a full-stack web developer that enjoys coding in Laravel and React.
Hi! I did it to the end exactly! but it zoomUser is undefined in the console. Please Help!
In this series I'll discuss how I solved problems with frontend technologies like React, Vue, Next, Nuxt, Gatsby, etc. in the style of tutorials.
Setup and Preliminary ServerMiddleware Work
Switching stacks

If you don't know what Twin Macro is, check it out! It's a great library that blends Tailwind CSS and Styled Component systems, like Emotion. I love using Twin because it lets me use Tailwind while separating my styling from my markup and methods. If...

Many developers know that full-stack apps with a Vue frontend can be quickly spun up with Laravel Jetstream. What many don’t know is that recently, the Laravel team made it easy to make an Inertia app with Laravel Breeze. In this article, we'll make ...

Extending the Rule Object with a DateTime Trait

Using Custom Console Commands

To make apps using Zoom's API, authentication is a must. You can either do this with JWT or OAuth. If you're building a third-party service or application, OAuth is the way to go. We'll not be using an SDK for this tutorial; everything will be done from scratch.
Preliminaries:
npm init next-app my-next-app && cd my-next-app. Of course, you can rename 'my-next-app' into anything you choose.Further setup:
ngrok http 3000. Change '3000' to whatever port your Next app will be listening on.Finally, insert the Forwarding address into 'Redirect URL for OAuth' and 'Whitelist URL' fields on the App Credentials page of your Zoom app.

The Job Begins:
https://zoom.us/oauth/authorize with a few params. useEffect to mount this address when the page loads. We'll also be using the hook useState.import React, {useEffect, useState} from 'react'
const IndexPage = () => {
const [url, setUrl] = useState(null)
const makeLink = () => {
const thisUrl = new URL('https://zoom.us/oauth/authorize')
thisUrl.searchParams.set('response_type', 'code')
thisUrl.searchParams.set('redirect_uri', process.env.NEXT_PUBLIC_NGROK_URL)
thisUrl.searchParams.set('client_id', process.env.NEXT_PUBLIC_ZOOM_CLIENT)
setUrl(thisUrl.href)
}
useEffect(() => {
makeLink()
}, [])
return (
<a href={url}>Start Zoom OAuth Process</a>
)
}
export default IndexPage

The Job Continues:
code param followed by a random string in the URL. We'll capture that using a data fetching feature called 'getServerSideProps'. This feature is used for pre-rendering with Next SSR. If you're familiar with writing Node, you won't have much of an issue here....
export const getServerSideProps = async ({req, res}) => {
const thisUrl = new URL(req.url, `http://${req.headers.host}`)
...
}
export default IndexPage
base64(CLIENT_ID:CLIENTSECRET). That's pseudocode of course, so let's turn that into real code. We'll be using Node's Buffer class, which helps in the handling of binary data.if (thisUrl.searchParams.get('code')){
const urlParam = thisUrl.searchParams.get('code')
const data = process.env.NEXT_PUBLIC_ZOOM_CLIENT_ID + ':' +
process.env.NEXT_PUBLIC_ZOOM_CLIENT_SECRET
const newData = Buffer.from(data, 'utf8')
const b64string = newData.toString('base64')
...
const zoomUrl = new URL('https://zoom.us/oauth/token')
zoomUrl.searchParams.set('grant_type', 'authorization_code')
zoomUrl.searchParams.set('code', urlParam)
zoomUrl.searchParams.set('redirect_uri', process.env.NEXT_PUBLIC_NGROK_URL)
code param is passed into the new URL in its code param.try {
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + b64string
}
}
const response = await fetch(zoomUrl.href, options)
const json = await response.json()
...
}
catch(e){
console.log(e)
}
code generated. We'll pass that code into the 'code' param in our new URL, and use the base-64 string we generated in our header. We wait for a response using the Fetch API (not naturally a part of Node but included with Next) and convert the response to JSON.try {
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + b64string
}
}
const response = await fetch(zoomUrl.href, options)
const json = await response.json()
if (json.access_token){
const newOptions = {
method: 'GET,
headers: {
'Authorization': 'Bearer ' + json.access_token
}
}
const preUser = await fetch('https://api.zoom.us/v2/users', newOptions)
const zoomUser = await preUser.json()
return {
props: {zoomUser}
}
}
}
catch(e){
console.log(e)
}
The Job Ends:
const IndexPage = ({zoomUser}) => {
console.log(zoomUser)
...
}
Conclusion: