How to implement OAuth2 in web apps in 5 easy steps: A beginner’s guide

Emmanuel Ugwu - Jul 28 '23 - - Dev Community

Authentication is the foundation of security for all modern technology. Every business, enterprise, and organization requires authentication, lowering the danger of compromising important user information.

Authentication is simply validating a user's information or identity. It plays a critical role in protecting sensitive data, maintaining user privacy, and granting users appropriate access to resources and functionalities within an application.

This guide demonstrates beginner-friendly steps to implement authentication in web apps with Appwrite’s Google OAuth.

The complete source code for this project is located here. Clone and fork it to get started.

Prerequisite

To follow along with this tutorial, the following are required:

  • A basic understanding of JavaScript and Next.js
  • Node and its package manager, npm. Install them from here
  • Access to an Appwrite Cloud account. Submit a request for Appwrite Cloud here
  • A Google account; create a free account here

Step 1: Project setup and installation

Let’s bootstrap a new Next.js project with the following command:



npx create-next-app <project-name>


Enter fullscreen mode Exit fullscreen mode

The command above triggers a command-line interface (CLI) where we can create our Next.js application. The image below shows the configuration options the CLI provides:

command-line interface

Navigate to the project directory and start a development server at https://localhost:3000/ in our browser.



cd <project-name> 
npm run dev


Enter fullscreen mode Exit fullscreen mode

NOTE: <project-name> above stands for the name of our app; we can call it any name we deem fit.

Step 2: Set up Google authentication

We'll head to Google Cloud Console to set up a Google authentication. Here, we’ll get an OAuth client ID for our application.

A client ID is an application-specific identifier that aids the client and server OAuth 2.0 authentication. Create a new project and name it appwrite-google-auth.

New project

After creating the project, click the APIs & Services tab to see the dashboard below.

APIs & Services Dashboard

On the left-hand menu, select the OAuth Consent Screen option. We must first configure our consent screen to create an OAuth client ID. A consent screen shows a summary of our project and its policies whenever our app requests authorizations from a user’s Google Account.

Click on Configure Consent Screen, then select External to give access to any test user with a Google Account, and click Create.

Select user type

Next, we’ll edit our app registration. Fill in the app registration form with the details below and click SAVE AND CONTINUE.

App Name Medic Care
User support email walterobrian@gmail.com
App logo LEAVE BLANK
Application home page http://localhost:3000/
Application privacy policy link LEAVE BLANK
Application terms of service link LEAVE BLANK
Authorized domains LEAVE BLANK OR ADD A REGISTERED APP DOMAIN IF THERE’S ONE
Developer contact information walterobrian@gmail.com

Edit app registration

Leave the Scopes and Test users configurations blank and click SAVE AND CONTINUE to complete the process.
On the left-hand menu, select the Credentials option to access the page where we can generate the Google client ID. At the top of this screen, click CREATE CREDENTIALS, then select the OAuth client ID option.

Create Credential

Fill in the OAuth client ID form with the details below and click the Create button.

Application type Web application
Name appwrite-auth
Authorized JavaScript origins - http://localhost:3000/
- http://localhost
Authorized redirect URIs - http://localhost:3000/
- http://localhost

The Authorized JavaScript origins URI is the development server of our application. Use http://localhost:3000 and http://localhost, or a hosted URI if the application is hosted.

The Authorized redirect URI is the link to which Google will redirect a user after a successful login. We can redirect a user to another link or return the user to the original link. Either way, include the URL here.

Finally, click the Create button to generate the Google client ID. We'll be redirected to the dashboard to see the newly created credentials. Copy the Google Client ID and Client Secret; we'll use them later.

OAuth client ID form
Google Client ID and  Client Secret

NOTE: Don’t share your Google Client ID or Client Secret.

Step 3: Create an Appwrite project

What is Appwrite?

Appwrite is a development platform that provides a powerful API and management console for building backend servers for web and mobile applications.

To use Appwrite in our Next.js application, install Appwrite’s client-side SDK (Software Development Kit) and Pink Design to style web applications.



npm install appwrite
npm install @appwrite.io/pink


Enter fullscreen mode Exit fullscreen mode

Log in to Appwrite Cloud and create a new project.

Create a new project

The new project will appear on the console. Next, copy the Project ID and API Endpoint. We’ll use this to set up our Next.js application.

NOTE: Don’t share your Project ID or API Endpoint.

Navigate to the Auth option and click the Settings tab. We want to enable a Google OAuth provider for our app. Click on the Google OAuth Provider tab and paste the Google Client ID and Client Secret we got from Google earlier.

Copy the Appwrite Authorized redirect URI for our Google OAuth provider and add it to our Google Cloud Console's list of Authorized redirect URIs.

Google OAuth Provider tab
Google Cloud Console

Step 4: Integrate Appwrite with our Next.js application

Let’s create a pages/component/ApiHelper.js file to house our Appwrite instance. Paste the Project ID and API Endpoint from Appwrite. This creates an instance to interact with Appwrite services.



import { Client, Account } from "appwrite";
const client = new Client();
 export const account = new Account(client);
 client
   .setEndpoint("http://localhost/v1") // Your API Endpoint
   .setProject("OUR_PROJECT_ID"); // Your project ID


Enter fullscreen mode Exit fullscreen mode

Next, we want to create an impression where any user not logged into the app would automatically be redirected to Google's OAuth Page.

To achieve this functionality, open the pages/index.js file, import the Appwrite instance from ApiHelper.js, and replace its default syntax with the code snippet below.



// pages/index.jsx
import React, { useEffect, useState } from "react";
import { account } from "./api/ApiHelper";
export default function Home() {
  const [userDetails, setUserDetails] = useState();
  const fetchUser = async () => {
    try {
      const data = await account.get();
      setUserDetails(data);
    } catch (error) {
      console.log("the error that happened:", error);
      return Login();
    }
  };
  useEffect(() => {
    fetchUser();
  }, []);
  const Login = () => {
    try {
      const response = account.createOAuth2Session(
        "google",
        "http://localhost:3000",
        "http://localhost:3000/login"
      );
      console.log(response);
    } catch (error) {
      console.error("Failed to create OAuth session:", error);
    }
  };
  return (
    <main>
      {userDetails ? (
          <div className="container u-padding-64 u-text-center">
            <p className="text u-normal">
              <b>Patient Name</b>: {userDetails.name}
            </p>
            <p className="text u-normal">
              <b>Email</b>: {userDetails.email}
            </p>
          </div>
        </div>
      ) : (
        <div className="container u-padding-64 u-text-center">
          <h1>Redirecting to authentication page...</h1>
        </div>
      )}
    </main>
  );
 }


Enter fullscreen mode Exit fullscreen mode

The code snippet above does the following:

  • Creates a useState() variable — userDetails, to hold user data
  • Executes the function — fetchUser, whenever the component is mounted. This function gets the data of a user that’s currently logged in, then assigns it to the userDetails variable
  • Automatically creates a Google OAuth session only if the user data isn’t present, which shows the current user isn’t logged in. This Google OAuth session grants a user access to log into the app
  • The Google OAuth session re-routes to the homepage only if the user successfully logs in

This is how the login page will look after applying the configurations above:

Step 5: Create a log in and log out feature

Next, we’ll create a pages/login.js file to log into the app manually. This file will create a Google OAuth session allowing users access to the app. Import the Appwrite instance from ApiHelper.js to initialize the session.



//pages/login.js
import React from "react";
import Link from "next/link";
import "@appwrite.io/pink";
import { account } from "./component/ApiHelper";
export default function Login() {
  const Login = () => {
    try {
      const response = account.createOAuth2Session(
        "google",
        "http://localhost:3000",
        "http://localhost:3000/login"
      );
      console.log(response);
    } catch (error) {
      console.error("Failed to create OAuth session:", error);
    }
  };
  return (
    <main>
      <nav className="u-flex u-cross-center u-main-space-between u-padding-32">
        <h2 className="logo u-padding-16 eyebrow-heading-1 u-or-text-pink">
          <Link href="/">MEDIC CARE</Link>
        </h2>
        <button className="button" onClick={() => Login()}>
          LOG IN
        </button>
      </nav>
      <div className="container u-padding-64">
        <p className="u-text-center u-padding-64 text u-normal">
          Log in to get user details.
        </p>
      </div>
    </main>
  );
}


Enter fullscreen mode Exit fullscreen mode

The Google OAuth session redirects to the homepage only if the user successfully logs in. To log out a user, head back to the pages/index.js file and add an Appwrite instance to delete the current user session and re-route the page to the login page.



//pages/index.js
export default function Home() {
  const Logout = async () => {
    try {
      await account.deleteSession("current");
      router.push("/login");
    } catch (error) {
      console.log("the error that happened:", error);
    }
  };
return (    
    <main>
      {userDetails ? (
        <div>
          <nav className="u-flex u-cross-center u-main-space-between u-padding-32">
<h2 className="logo u-padding-16 eyebrow-heading-1 u-color-text-pink">MEDIC CARE</h2>
            <div>
   <button className="button" onClick={() => Logout()}> LOG OUT </button>
            </div>
          </nav>
       // User details
      ) : (
        <div className="container u-padding-64 u-text-center">
          <h1>Redirecting to authentication page...</h1>
        </div>
      )}
    </main>
    );
  }


Enter fullscreen mode Exit fullscreen mode

Here’s a demo of how the Google authentication will turn out after applying the necessary configurations:

Conclusion

Following these five steps, developers can implement OAuth2 in their web apps using Google OAuth and Appwrite SDK, providing users with a safe and efficient authentication process.

Resources

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