How to add GitHub authentication to a Next.js application
Tags: javascript, github, appwritehack, git
Published: 2022-07-18 23:56:03

Authentication enables organizations to keep their networks secure by verifying the identity of a user attempting to gain access to their network or protected resources. 

This means authorizing a human-to-machine transfer of credentials during interactions on a network to confirm a user's authenticity.

[Appwrite](https://appwrite.io/?utm_source=hackmamba&utm_medium=hackmamba-blog) is an end-to-end backend server for web, mobile, native, or backend apps packaged as a set of Docker microservices. We can use these Appwrite services to integrate authentication & sign-in methods within our application quickly.

This post discusses how to authenticate a Next.js application using Appwrite's GitHub OAuth provider.

The complete source code is in this [Git](https://github.com/Kizmelvin/appwrite-github-auth)[H](https://github.com/Kizmelvin/appwrite-github-auth)[ub Repository](https://github.com/Kizmelvin/appwrite-github-auth).

## Prerequisites

To understand this article, you will need to meet the following requirements: 

- Installation of Node.js 
- [Docker](https://www.docker.com/get-started/) installation
- Basic knowledge of JavaScript and React.js
- An Appwrite instance; check out this [article](https://dev.to/hackmamba/create-a-local-appwrite-instance-in-3-steps-19n9?utm_source=hackmamba&utm_medium=hackmamba) on how to set up an instance
- A GitHub account; [signup](https://github.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F&source=header-home) is completely free


## Setting up Appwrite and GitHub

First, we’ll start the [Appwrite](https://appwrite.io/?utm_source=hackmamba&utm_medium=hackmamba-blog) instance on our local machine and navigate to the specified hostname and port `http://localhost:80`. Log in or sign up to create a new application.


![](https://paper-attachments.dropbox.com/s_884810B4F12418144BB5D8586E4DA36816941F58663193EAC0A330CADEBD5127_1655888212701_Screenshot+2022-06-17+at+11.35.26.png)


After successful signup, click on the **Create Project** button and choose a name for the project.


![](https://paper-attachments.dropbox.com/s_884810B4F12418144BB5D8586E4DA36816941F58663193EAC0A330CADEBD5127_1656059693858_Screenshot+2022-06-24+at+09.30.04.png)
![](https://paper-attachments.dropbox.com/s_884810B4F12418144BB5D8586E4DA36816941F58663193EAC0A330CADEBD5127_1656084571049_appwrt2.png)


Click the settings tab and save the **Project ID** and the **API Endpoint**. We’ll use this to set up the Next.js application.


![](https://paper-attachments.dropbox.com/s_884810B4F12418144BB5D8586E4DA36816941F58663193EAC0A330CADEBD5127_1656084673793_appwrt4.png)


Next, click on the **Users** tab from the menu on the left-hand side, navigate to **Settings**, scroll down, and toggle the GitHub OAuth2 Provider.


![](https://paper-attachments.dropbox.com/s_884810B4F12418144BB5D8586E4DA36816941F58663193EAC0A330CADEBD5127_1656059821856_Screenshot+2022-06-24+at+09.32.55.png)
![](https://paper-attachments.dropbox.com/s_884810B4F12418144BB5D8586E4DA36816941F58663193EAC0A330CADEBD5127_1656059888136_Screenshot+2022-06-24+at+09.31.21.png)


Now, grab the OAuth redirect URI and add GitHub authentication. Sign in to GitHub, navigate to `settings/profile`, scroll down, and click on the **Developer settings** tab.


![](https://paper-attachments.dropbox.com/s_884810B4F12418144BB5D8586E4DA36816941F58663193EAC0A330CADEBD5127_1655985917614_Screenshot+2022-06-23+at+13.00.36.png)


Select the **OAuth Apps** tab on the left and click on the New Auth App button.


![](https://paper-attachments.dropbox.com/s_884810B4F12418144BB5D8586E4DA36816941F58663193EAC0A330CADEBD5127_1655986330249_Screenshot+2022-06-23+at+13.06.38.png)


Next, choose a name for the application, add a Homepage URL, paste the OAuth redirect URI, and click the green **R****egister** **A****pplication** button.


![](https://paper-attachments.dropbox.com/s_884810B4F12418144BB5D8586E4DA36816941F58663193EAC0A330CADEBD5127_1655995414032_Screenshot+2022-06-23+at+15.37.21.png)


Grab the Client ID, click on the **Generate a new secret button**, authorize GitHub, and copy the generated **Client secret**.


![](https://paper-attachments.dropbox.com/s_884810B4F12418144BB5D8586E4DA36816941F58663193EAC0A330CADEBD5127_1656083807035_Screenshot+2022-06-24+at+16.13.57.png)


Now, switch over to Appwrite and paste the Client ID in the App ID box and Client secret in the App Secret.


![](https://paper-attachments.dropbox.com/s_884810B4F12418144BB5D8586E4DA36816941F58663193EAC0A330CADEBD5127_1656084806903_appwrt3.png)



## Setting up Next.js the Application

First, let’s run the following command in the terminal to create a new Next.js application:


    npx create-next-app appwrite-github-app


The above command creates a starter Next.js application in our **appwrite-github-app** folder.

Next, navigate into the project directory with the following command:


    cd appwrite-github-app

The, run the following command to install [A](https://www.npmjs.com/package/appwrite)[ppwrite](https://www.npmjs.com/package/appwrite) npm packages and start the application:


    npm install appwrite #install appwrite package
    npm run dev #start the dev server


Next.js will start the development server at [http://localhost:3000](http://localhost:3000).


## Integrating the GitHub Authentication in the Next.js App

First,  create a `utils.js` file in the root directory with the following snippets:

```js
    import { Appwrite } from "appwrite";
    const appwriteSdk = new Appwrite();
    appwriteSdk
      .setEndpoint("http://localhost/v1")
      .setProject("<PROJECT ID HERE>");
    export default appwriteSdk;
```

Here, we imported `Appwrite` and created a new instance of it, passing our Project ID and API Endpoint that we saved earlier. 

Next, modify the `index.js` with the following snippets:

```js
 //pages/index.js
    import Head from "next/head";
    import styles from "../styles/Home.module.css";
    import appwriteSDK from "../utils";
    export default function Home() {
      const authRedirect = async () => {
        try {
          await appwriteSDK.account.createOAuth2Session(
            "github",
            "http://localhost:3000/welcome",
            "http://localhost:3000"
          );
        } catch (error) {
          console.log(error);
        }
      };
      return (
        <div className={styles.container}>
          <Head>
            <title>Appwrite Authentication with Github</title>
            <meta name="description" content="Generated by create next app" />
            <link rel="icon" href="/favicon.ico" />
          </Head>
          <main className={styles.main}>
            <h1>Hello there!</h1>
            <button onClick={authRedirect}>Login with Github</button>
          </main>
        </div>
      );
    }
```

In the snippets above we:

- Imported **appwriteSDK** from the `utils.js` file, created `authRedirect()` function, and provided successful and failed authorization URLs inside the `authRedirect()` function.
- Returned the **Login with Git****H****ub** button and passed the `authRedirect()` function to it.

Notice we provided a `/welcome` route we have not created yet; create a `welcome.js` file inside the **pages** folder with the following snippets:

```js
    //pages/welcome.js
    import styles from "../styles/Home.module.css";
    import "bootstrap/dist/css/bootstrap.min.css";
    import { useEffect, useState } from "react";
    import { useRouter } from "next/router";
    import appwriteSDK from "../utils";
    function welcome() {
      const [user, setUser] = useState(null);
      const router = useRouter();
      const getUser = async () => {
        const userData = (await appwriteSDK) && appwriteSDK.account.get();
        userData
          .then((res) => setUser(res))
          .catch((err) => {
            router.push("/");
            console.log(err);
          });
      };
      const logOut = async () => {
        await appwriteSDK.account.deleteSession("current");
        alert("logout successful");
        router.push("/");
      };
      useEffect(() => {
        getUser();
      }, []);
      return (
        <div className={styles.container}>
          <main className={styles.main}>
            <h1 className="mb-4">Github Authenticated Page</h1>
            {user && (
              <div>
                <p>
                  User:{" "}
                  <span className="fs-3 fw-bold text-capitalize">{user.name}</span>
                </p>
                <p>
                  Email: <span className="fs-3 fw-normal">{user.email}</span>
                </p>
                <button onClick={logOut} className="btn-danger mt-2 fs-3">
                  Log Out
                </button>
              </div>
            )}
          </main>
        </div>
      );
    }
    export default welcome;
```

In the snippets above we:

- Imported **useState**, **useEffect**, and **useRouter** hooks; created user and router constants with **useState** and **useRouter**, respectively.
- Created the `getUser()` function; inside it, we receive the authorized user account details and update the user state.
- Created the `logOut()` function that logs out a user.
- Conditionally returned the user details and created a **Log Out** button in the `return()` function.

In the browser, the application will look like this:


![](https://paper-attachments.dropbox.com/s_884810B4F12418144BB5D8586E4DA36816941F58663193EAC0A330CADEBD5127_1656103543466_appwrite5.png)


When we click on the **Login with Git****H****ub** button, we’ll be redirected to the authorization page.


![](https://paper-attachments.dropbox.com/s_884810B4F12418144BB5D8586E4DA36816941F58663193EAC0A330CADEBD5127_1656103645324_appwrt6.png)


[Appwrite](https://appwrite.io/?utm_source=hackmamba&utm_medium=hackmamba-blog) will redirect us to the  `/welcome` route on successful authorization, and we'll display the authenticated user details there.


![](https://paper-attachments.dropbox.com/s_884810B4F12418144BB5D8586E4DA36816941F58663193EAC0A330CADEBD5127_1656106664984_appwrt8.png)



## Conclusion

This post discussed adding authentication to a Next.js application with Appwrite’s OAuth2 GitHub provider. 

## Resources

These resources might be helpful:

- [Setting up Appwrite instance locally](https://dev.to/hackmamba/create-a-local-appwrite-instance-in-3-steps-19n9?utm_source=hackmamba&utm_medium=hackmamba)
- [Getting started with Appwrite](https://appwrite.io/docs/getting-started-for-web?utm_source=hackmamba&utm_medium=hackmamba)
- [Building Git](https://docs.github.com/en/developers/apps/building-oauth-apps/creating-an-oauth-app)[H](https://docs.github.com/en/developers/apps/building-oauth-apps/creating-an-oauth-app)[ub OAuth App](https://docs.github.com/en/developers/apps/building-oauth-apps/creating-an-oauth-app)