How to authenticate a Next.js application using Zoom

Demola Malomo - Jun 13 '22 - - Dev Community

Authentication is an integral part of building robust and secure applications. Companies such as Zoom, Apple, Google, and Facebook are constantly creating innovative ideas that help their users securely share information with third-party applications without remembering multiple credentials. The technology facilitating this process is known as Open Authentication (OAuth), a framework that enables users to grant access to websites or applications without compromise.

In this post, we will learn how to authenticate a Next.js application using Appwrite’s Zoom OAuth provider. The project’s GitHub repository can be found here.

Prerequisites

To fully grasp the concepts presented in this tutorial, the following requirements apply:

  • Basic understanding of JavsScript and React
  • Docker installation
  • An Appwrite instance; check out this article on how to set up an instance
  • A Zoom account; signup is completely free

Getting started

We need to create a Next.js starter project by navigating to the desired directory and running the command below in our terminal.

    npx create-next-app zoom-auth && cd zoom_auth
Enter fullscreen mode Exit fullscreen mode

The command creates a Next.js project called zoom-auth and navigates into the project directory.

Installing dependencies

Installing TailwindCSS
TailwindCSS is a utility-first CSS framework packed with classes to help us style our web page. To use it in our application, run the command below in our terminal.

    npm install -D tailwindcss postcss autoprefixer
    npx tailwindcss init -p
Enter fullscreen mode Exit fullscreen mode

The command installs TailwindCSS and its dependencies and generates tailwind.config.js and postcss.config.js files.

Next, we need to update tailwind.config.js file with the snippet below:

    module.exports = {
      content: [
        "./pages/**/*.{js,ts,jsx,tsx}",
        "./components/**/*.{js,ts,jsx,tsx}",
      ],
      theme: {
        extend: {},
      },
      plugins: [],
    }
Enter fullscreen mode Exit fullscreen mode

Finally, we need to add TailwindCSS directives to our application. The directives give our application access to TailwindCSS utility classes. To do this, navigate to the styles folder and update the globals.css files in it with the snippet below:

    @tailwind base;
    @tailwind components;
    @tailwind utilities;
Enter fullscreen mode Exit fullscreen mode

Installing Appwrite
Appwrite is a development platform that provides a powerful API and management console for building backend servers for web and mobile applications. To install it, run the command below:

    npm install appwrite
Enter fullscreen mode Exit fullscreen mode

Creating a new Appwrite project

To create a new project, start up the Appwrite instance on your machine and navigate to the specified hostname and port http://localhost:80. Next, we need to log in to our account or create an account if we don’t have one.

Appwrite running

You can learn more about setting up Appwrite here. On the console, click on the Create Project button, input appwrite_zoom as the name, and click Create.

Create project
Enter project name

The project dashboard will appear on the console. Next, click on the settings tab and copy the Project ID and API Endpoint.

Copy  Project ID and API Endpoint

Next, we’ll navigate to our project root directory and create a helper folder; here, create an utils.js file and add the snippet below:

    import { Appwrite } from 'appwrite';
    const sdk = new Appwrite();
    sdk.setEndpoint('http://localhost/v1').setProject('ADD YOUR PROJECTID HERE');

    export default sdk;
Enter fullscreen mode Exit fullscreen mode

Activating Zoom auth method on Appwrite
To do this, navigate to the Users menu, select the Settings tab, and enable the Zoom option:

navigate to settings

Upon enabling the Zoom option, we will be required to fill in the App ID and App Secret. We will fill them in shortly. However, we need to copy the callback URI provided by Appwrite. We need it to authenticate our application.

Copy callback URI

Create an App on Zoom
To enable Zoom’s OAuth provider with Appwrite, we need to sign in/sign up on Zoom’s marketplace and create an application.

Click on the Develop dropdown, and select Build App:

Build App

Click on Create under the OAuth section:

Input appwrite_zoom as the App Name, select Account-level app, and Create.

Create app

Next, we paste the callback URI we copied earlier into the Redirect URL for OAuth and Add allow lists fields. We also need to copy the Client ID and Client Secret and paste them into our Appwrite configuration. Then, click Update.

Paste URI and copy Client ID and Client Secret
Paste URI

Update Zoom provider on Appwrite

Navigate to the Information menu and input Appwrite authentication using Zoom as the Short description and the Long description.

Fill in description

On the same Information menu, scroll down to the Developer Contact Information section and fill in your Name and Email Address.

Navigate to the Scope menu, click on the Add Scopes button, click User, and then select View all user information. This scope selected will give our application access to the user’s information.

add scope
select user

Building the authentication in Next.js

The application will contain two pages; a page to log in and another page to show logged-in user details.

Creating a login page
To do this, we need to update the content of the index.js file inside the pages folder with the snippet below:

    import Head from 'next/head';
    import styles from '../styles/Home.module.css';
    import sdk from '../helper/utils';

    export default function Home() {
      const loginWithZoom = async () => {
        try {
          await sdk.account.createOAuth2Session(
            'zoom',
            'http://localhost:3000/dashboard'
          );
        } catch (error) {
          console.log(error);
        }
      };

      return (
        <div className={styles.container}>
          <Head>
            <title>Appwrite|Zoom</title>
            <meta name='description' content='Appwrite and Zoom' />
            <link rel='icon' href='/favicon.ico' />
          </Head>
          <main className={styles.main}>
            <h1 className='text-2xl font-medium text-indigo-700'>
              Auth with Appwrite and Zoom
            </h1>
            <div className='w-11/12 md:w-2/4 flex flex-col items-center p-16 border rounded-lg'>
              <p className='text-sm mb-4'>Click on the button below to login</p>
              <button
                onClick={loginWithZoom}
                className='px-6 py-2 h-10 bg-black text-white rounded-lg'
              >
                Login with zoom
              </button>
            </div>
          </main>
        </div>
      );
    }
Enter fullscreen mode Exit fullscreen mode

The snippet above does the following:

  • Imports the required dependencies.
  • Creates a loginWithZoom asynchronous function that uses the Appwrite sdk we initialized earlier to authenticate using zoom as the provider and http://localhost:3000/dashboard as the URL it redirects to when the authentication is successful. We will create the dashboard page in the next section.
  • Creates markup for the login page.

Creating a dashboard page
Next, in the same pages folder, we need to create a dashboard.js file and update it with the snippet below:

    import Head from 'next/head';
    import styles from '../styles/Home.module.css';
    import sdk from '../helper/utils';
    import { useEffect, useState } from 'react';
    import { useRouter } from 'next/router';

    export default function Dashboard() {
      const [session, setSession] = useState(null);
      const router = useRouter();

      const getSession = async () => {
        const data = (await sdk) && sdk.account.get();
        data
          .then((res) => setSession(res))
          .catch((err) => {
            router.push('/');
            console.log(err);
          });
      };

      useEffect(() => {
        getSession();
      }, []);

      const logOut = async () => {
        await sdk.account.deleteSession('current');
        alert('logout successful');
        router.push('/');
      };

      return (
        session && (
          <div className={styles.container}>
            <Head>
              <title>Appwrite|Zoom</title>
              <meta name='description' content='Appwrite and Zoom' />
              <link rel='icon' href='/favicon.ico' />
            </Head>
            <main className={styles.main}>
              <h1 className='text-2xl font-medium text-indigo-700 mb-4'>
                Authenticated Page with Appwrite and Zoom
              </h1>
              <p>
                Welcome:{' '}
                <span className='font-medium capitalize'>{session.name}</span>
              </p>
              <p>
                email:{' '}
                <span className='font-medium text-indigo-700'>{session.email}</span>
              </p>
              <button
                onClick={logOut}
                className='px-6 py-2 h-10 mt-12 border-2 border-black text-black rounded-lg'
              >
                Log Out
              </button>
            </main>
          </div>
        )
      );
    }
Enter fullscreen mode Exit fullscreen mode

The snippet above does the following:

  • Imports the required dependencies.
  • Creates states and route variables to manage logged in user sessions and route accordingly.
  • Creates a getSession function to get the logged-in user session and re-route to the login page if the session is empty. We also called the function upon page load using the useEffect hook.
  • Creates a logOut function to log the user out.
  • Includes markup to show the user’s name and email.

With that done, we can start a development server using the command below:

    npm run dev
Enter fullscreen mode Exit fullscreen mode

https://media.giphy.com/media/iKBpFwHoKzTOkUTrws/giphy.gif

Conclusion

This post discussed how to authenticate a Next.js application using Appwrite’s Zoom OAuth provider.

These resources might be helpful:

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .