# Zoom OAuth with a NuxtJS App, Part 1

Some weeks ago we discussed how to do [Zoom OAuth with Next.js](https://blog.lloydmiller.tech/zoom-oauth-with-nextjs-app). As was said there, we need to authenticate our calls to Zoom's API in order for us to use it, and we 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:**
- Make sure you have a Zoom account and register your app in [Zoom's Marketplace](https://marketplace.zoom.us/). More details on how to do so can be found [here](https://marketplace.zoom.us/docs/guides/build/oauth-app#register-your-app).
- [Download and install Ngrok](https://ngrok.com/download). We'll need it because Zoom doesn't allow redirects to localhost.
    * Run Ngrok by using your terminal and running `ngrok http 3000` wherever your Ngrok executable file is stored. 
- Presuming that you already have Nuxt [downloaded and set up](https://nuxtjs.org/docs/2.x/get-started/installation), you'll need to set up your environment variables.
    * Create a ***.env*** file. Here we will house our Zoom Client ID and Client Secret. You should place your Ngrok URL here too.
    * For this tutorial, we'll name our variables thusly: `NUXT_ENV_ZOOM_CLIENT_ID`, `NUXT_ENV_ZOOM_CLIENT_SECRET`, and `NUXT_ENV_BASE_URL`. **NB:** We use the prefix `NUXT_ENV_`to inject it straight into the process environment, so we don't have to do anything extra in ***nuxt.config.js***.
- Insert the Ngrok URL into 'Redirect URL for OAuth' and 'Whitelist URL' fields on the App Credentials page of your Zoom app.
- [Scopes are extremely important](https://marketplace.zoom.us/docs/guides/auth/oauth/oauth-scopes) so don't forget to add them to your app dashboard!
- Run `npm run dev`!

**The Work Begins:** Here we're going to make a simple link that when clicked will help kick off the whole process. 
- In your pages folder, create ***index.vue*** if it's not already there. We will put `link` as a property so we can manipulate it and bind it to our `a` tag via `v-bind:href`. We need the link to be available when our page is mounted, so we'll use Vue's `mounted` hook.
- We'll also be using the [URL interface](https://developer.mozilla.org/en-US/docs/Web/API/URL) which should be available to all modern browsers.

```
<template>
    <a :href="link">Create Zoom link</a>
</template>

<script>
export default {
    data(){
        return {
            link: '',
        }
    }, 
    mounted(){
        this.getZoomLink()
    },
    methods: {
        getZoomLink(){
            let url = new URL('https://zoom.us/oauth/authorize')
            url.searchParams.set('response_type', 'code')
            url.searchParams.set('redirect_uri', process.env.url)
            url.searchParams.set('client_id', process.env.zoomclient)
            this.link = url.href
        }, 
    }    
}
</script>
``` 
- When you click the link, a page describing your app and the info that it's requesting will show up (if you're logged in). Once you click on the 'Authorize' button, it will redirect you to the `redirect_uri` that you set.

**The Work Continues:** You should now see `code` in the query string in your browser's URL bar. We'll need to use this string to get our access code. 
- To get our `code`, we'll use `this.$route.query`. It returns an object, so we'll first check to see if it is empty with `Object.keys()` to ensure we only run it when this query string is set. We'll pass it on to a property called `code` so that we can use its value elsewhere.
    * We'll be using the `created` lifecycle hook instead of `mounted` for this part. This hook is usually used for fetching data on initialization and fires right [before the mounting](https://www.digitalocean.com/community/tutorials/vuejs-component-lifecycle) of our component.

```
data(){
    return {
        link: '',
        code: ''
    }
},
created(){
    const obj_length = Object.keys(this.$route.query).length
    if (obj_length > 0){
        this.code = this.$route.query.code
    }
},
mounted(){
    this.getZoomLink()
},
```
- Now we'll create a method that will send this data to our ***serverMiddleware***. It will run immediately after we get the `code` string. 
```
created(){
    const obj_length = Object.keys(this.$route.query).length
    if (obj_length > 0){
        this.code = this.$route.query.code
        this.getZoomUser()
    }
},
...
methods: {
    async getZoomUser(){
        let options = {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json'
            }
        }  
        let response = await fetch(`/api/access-token?code=${this.code}`, options)
        let user = await response.json()
    },
}
```

**The Work Ends:** All Zoom API endpoints will need to be accessed from the server-side, hence, we'll need to use Nuxt ***serverMiddleware***. Seriously, don't even try using the client. You'll get a lot of CORS issues. Our ***serverMiddleware*** will act as an API that will communicate with Zoom's API.
- The first thing we'll need to do is create an ***api/*** folder in the root, then create a file that will house our ***serverMiddleware***. I've named it ***zoom-token.js***.
- Now we'll register our ***serverMiddleware*** in our ***nuxt.config.js*** file. We'll set a proxy for our API, and tell Nuxt where exactly the API's handler function is.

```
serverMiddleware: [
    {path: '/api/access-token', handler: '~/api/zoom-token.js'},
]
```
- Now we can begin work on our ***serverMiddleware***. If we log our request to the console (in our terminal, not the browser), we'll see all the related properties, methods, and data, including our query string.

```
export default function(req, res){
    console.log(req)
}
```

**Conclusion:** 
- In our next post, we'll go deeper into ***serverMiddleware*** and show how we can return our data to the client-side.

