Integrating a secure authentication system is a crucial development step that not only provides a safe environment for users but also instills trust in your product. This system ensures that their data is protected and that only authorized individuals can access the application.

Building a secure authentication from the ground up can be a time-consuming process that requires a thorough understanding of authentication protocols and processes, especially when handling different authentication providers.

Using NextAuth, you can shift your focus to building the core features. Read on to learn how to integrate Google social login in your application using NextAuth.

How Does NextAuth Works

NextAuth.js is an open-source authentication library that simplifies the process of adding authentication and authorization functionality to Next.js applications as well as customizing authentication workflows. It provides a range of features such as email, passwordless authentication, and support for various authentication providers such as Google, GitHub, and more.

a login page is displayed on a samsung device

At a high level, NextAuth acts as a middleware, facilitating the authentication process between your application and the provider. Under the hood, when a user attempts to log in, they are redirected to Google's sign-in page. Upon successful authentication, Google returns a payload that includes the user's data, such as their name and email address. This data is used to authorize access to the application and its resources.

Using the payload data, NextAuth creates a session for each authenticated user and stores the session token in a secure HTTP-only cookie. The session token is used to verify the user's identity and persist their authentication status. This process also applies to other providers with slight variations in the implementation.

Register Your Next.js Application on Google Developer Console

NextAuth provides support for Google authentication service. However, for your application to interact with Google APIs and allow users to authenticate with their Google credentials, you will need to register your app on the Google developer console and obtain a Client ID and Client Secret.

To do that, navigate to Google Developer Console. Next, sign in with your Google account to access the console. Once logged in, create a new project.

Create Project on Google Developer Console

On the project's overview page, select the APIs and Services tab from the list of services on the left menu pane and finally, the Credentials option.

Google Developer Console settings

Click on the Create Credentials button to generate your Client ID and Client Secret. Next, specify the type of application from the given options and then provide a name for your application.

Setting up a google client id and secret by clicking the create credentials button

Afterward, specify your app's home route URL and finally specify the authorized redirect URI for your application. For this case, it should be http://localhost:3000/api/auth/callback/google as specified by NextAuth's Google provider settings.

OAuth Client Settings

Upon successful registration, Google will provide you with a Client ID and Client Secret for use in your app.

Set Up NextJS Application

To get started, create a Next.js project locally:

        npx create-next-app next-auth-app
    

After the setup is complete, navigate to the newly created project directory and run this command to spin up the development server.

        npm run dev
    

Open your browser and navigate to http://localhost:3000. This should be the expected result.

nextjs dev server start screen

You can find this project's code in its GitHub repository.

Setting Up the .env File

In your project's root folder, create a new file and name it .env to hold your Client ID, Secret, and the base URL.

        NEXT_PUBLIC_GOOGLE_CLIENT_ID= 'client ID'
NEXT_PUBLIC_GOOGLE_CLIENT_SECRET= 'secret'
NEXT_PUBLIC_NEXTAUTH_URL= 'http://localhost:3000'

The NextAUTH URL is used to specify the base URL of your application, which is used for redirecting users after authentication is completed.

Integrate NextAuth in Your Next.js Application

First, install NextAuth's library into your project.

        npm install next-auth
    

Next, in the /pages directory, create a new folder and name it api. Change the directory to the api folder, and create another folder called auth. In auth folder, add a new file and name it [...nextauth].js and add the following lines of code.

        import NextAuth from "next-auth/next";
import GoogleProvider from "next-auth/providers/google";
export default NextAuth({
    providers:[
        GoogleProvider({
            clientId:process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID,
            clientSecret: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_SECRET,
        }),
    ]

});

This code configures Google as the authentication provider. The NextAuth function defines the Google provider configuration object that takes in two properties: a Client ID and a Client Secret which initializes the provider.

Next, open the pages/_app.js file and make the following changes to the code.

        import '../styles/globals.css'
import { SessionProvider } from "next-auth/react"
function MyApp({ Component, pageProps: { session, ...pageProps } }) {
 return (
   <SessionProvider session={session}>
     <Component {...pageProps} />
   </SessionProvider>
 )
}
export default MyApp

NextAuth's SessionProvider component provides authentication state management functionality to the Next.js app. It takes a session prop that contains the authentication session data returned from Google's API which includes user details such as their ID, email, and access token.

By wrapping the MyApp component with the SessionProvider component, the authentication session object with user details is made available throughout the application, enabling the application to persist and render pages based on their authentication state.

Configure the index.js File

Open the pages/index.js file, delete the boilerplate code, and add the code below to create a login button that routes users to a login page.

        import Head from 'next/head'
import styles from '../styles/Home.module.css'
import { useRouter } from 'next/router';

export default function Home() {
  const router = useRouter();
  
  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <h1 className={styles.title}>
          Welcome to <a href="https://nextjs.org">Next.js!</a>
        </h1>

        <p className={styles.description}>
          Get started by signing in{' '}
          <code className={styles.code}>with your Google Account</code>
          <button className={styles.loginButton}
          onClick={() => router.push('/Login')}> Login</button>
        </p>
      </main>

    </div>
  )
}

This code uses Next.js useRouter hook to handle routing within the application by defining a router object. When the login button is clicked, the handler function calls the router.push method to redirect the user to the login page.

Create a Login Authentication Page

In the pages directory, create a new file Login.js, then add the following lines of code.

        import { useSession, signIn, signOut } from "next-auth/react"
import { useRouter } from 'next/router';
import styles from '../styles/Login.module.css'


export default function Login() {
  const { data: session } = useSession()
  const router = useRouter();
  if (session) {
    return (
      <div className={styles.container}>
        <h1 className="title">Create Next App</h1>
        <div className={styles.content}>
             <h2> Signed in as {session.user.email} <br /></h2>
              <div classname={styles.btns}>
              <button className={styles.button} onClick={() => router.push('/Profile')}>
                 User Profile
             </button>
              <button className={styles.button} onClick={() => {
                  signOut()
              }}>
                 Sign out
             </button>
              </div>
        </div>
      </div>

    )
  }
  return (
    <div className={styles.container}>
       <h1 className="title">Create Next App</h1>
      <div className={styles.content}>
          <h2> You are not signed in!!</h2>
      <button className={styles.button}
      onClick={() => signIn()}>Sign in</button>
      </div>
    </div>
  )
}

useSession, signIn, and signOut are hooks provided by next-auth. useSession hook is used to access the current user session object once a user signs in and is successfully authenticated by Google.

This allows Next.js to persist the authentication state and render the user details on the client side of the app, in this case, the email.

Moreover, using the session object, you can easily build custom user profiles for your application and store the data in a database such as PostgreSQL. You can connect a PostgreSQL database with your Next.js application using Prisma.

The signOut hook allows a user to sign out of the application. This hook will delete the session object created during the sign-in process and the user will be signed out.

Go ahead and spin up the development server to update the changes and head over to your Next.js application running on the browser to test the authentication functionality.

        npm run dev
    

Further, you can use Tailwind CSS with your Next.js app to style the authentication models.

Authentication Using NextAuth

NextAuth supports multiple authentication services that can easily be integrated into your Next.js applications to handle client-side authentication.

Additionally, you can integrate a database to store your users' data and the access token to implement server-side authentication for subsequent authentication requests since NextAuth provides support for different database integrations.