Back

User Authentication with Google Next-Auth

User Authentication with Google Next-Auth

In user’s based application, there is a need for user authentication and management to be able to provide services to different users. Rather than setting up complex login systems, NextJs provides us with the option to setup different modes of login integrations using the Next-auth package.

Installing Dependencies

This tutorial makes use of the Next.js authentication package, if you do not have Next.js installed you can install it via the command line using the following command in CLI:

npm install create-next-app authentication

The above command creates a folder called authentication with the Next.js framework setup for use. Next, you can install the Next-authentication package with the following command:

npm i next-auth

With this, you will have all the dependencies required to follow up with this tutorial set up and can proceed with setting up user authentication in your next application.

What is JWT?

JSON Web Token (JWT) is a standard that is used to create tokens for granting users access to a particular web application. It works behind the scenes, and being generated by the server it certifies the user’s identity. We will need to generate a token to use when integrating our google authentication.

Creating our Google API route

To setup Google authentication in our Next.js app, we will need to create our API endpoints. Thanks to Next.js provision for API handling, we can easily create API routes in the pages/api directory. In Next.js, by default all files in this directory are automatically treated as API endpoints, making it simple to use.

For the authentication endpoint, create a folder name auth in the pages/api folder and within it create a file named […nextauth].js. In this file. first we add imports for the Next-auth package:

import NextAuth from "next-auth";
import GoogleProvider from 'next-auth/providers/google'

Then we set up the API routes with the Google access credentials and JWT token.

export default NextAuth({
  providers: [
    GoogleProvider({
      clientId: "GOOGLE_CLIENT_ID",
      clientSecret: "GOOGLE_CLIENT_SECRET",
      authorizationUrl: 'https://accounts.google.com/o/oauth2/v2/auth?prompt=consent&access_type=offline&response_type=code',
    })
  ],
  jwt: {
    encryption: true
  },
  secret: "secret token",
  //Callback here
});

Above, we set up the Next-auth authentication provider as the Google authentication method. We will later add our access credentials to be able to make use of this and then create a JWT token which will authenticate the user.

Using a callback to restrict unauthorized access

We can create a callback function to restrict access of unathorized users using the JWT token

...
callbacks: {
    async jwt(token, account) {
      if (account ?.accessToken) {
        token.accessToken = account.accessToken
      }
      return token;
    },
    redirect: async (url, _baseUrl)=>{
      if (url === '/user') {
        return Promise.resolve('/')
      }
      return  Promise.resolve('/')
    }
}
});

We have setup a redirect URL that will redirect unauthenticated users who access the user route which we will later create, or any other route back to the home page upon authentication.

Configuring session states

To make use of Next-auth in the app, we will need to wrap our our _app.js file components as shown below:

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

Open Source Session Replay

OpenReplay is an open-source, session replay suite that lets you see what users do on your web app, helping you troubleshoot issues faster. OpenReplay is self-hosted for full control over your data.

replayer.png

Start enjoying your debugging experience - start using OpenReplay for free.

Setting up the sign-in page functionality

With Next-auth added to our application, we can now build our sign in page. First, we will set up our page to display the Sign in button if the user is not authenticated, else it returns our application. To do this, we modify the index.js file as shown below:

import { useSession, signIn, signOut } from "next-auth/react"

export default function Home() {
  const { data: session } = useSession();
  if (session) {
    return (
      <div className={styles.container}>
        Welcome user<br />
        <button onClick={() => signOut()}>Sign out</button>
      </div>
    );
  }
  return (
    <div className={styles.container}>
      Click to sign into your user account <br />
      <button onClick={() => signIn()}>Sign in</button>
    </div>
  );
}

The code above checks if the user has Session. If there is no Session, the Sign in button is returned, else it returns the Sign out button.

With this setup we are almost ready to test our Google login functionality, we just need to add our access credentials to be able to make use of this service.

Configuring Google Cloud Console API credentials

To get Google access credentials, you will need to login to the Google Cloud console. Sign in using your Google account and create a new project. Under + Create credentials in the top-menu bar select OAuth Client id. If requested to “Configure Consent Screen”, click on this button. On the new page that opens up, select external for the user type and click on create. Next, input your app name and email then save and continue. Leave the scope and Test users section empty and click on “Save and Continue”. Back on the dashboard, repeat the first step and click on Oauth Client id. Select “Web application” for the application type. Click on Add URI and enter http://localhost. Finally, in the Authorized redirect URIs section, click Add URI and in the field provided, key in http://localhost/api/auth/callback/google. Then create the authentication key. Copy the client ID and the client secret and add it to your application for use.

With this added, we can now log into the application using the Google email login. You can run your app via CLI with the following command and view it in your browser:

npm run dev

Note that after you’ve deployed your application to production, you’ll have to change the localhost part of that configuration into your actual host name.

Creating a protected route

With Next-auth we can also set up protected routes. Create a file called protectedpage.js in the pages directory and populate it wilth the following code:

import { getSession } from "next-auth/react";
import React from "react";
function protectedpage() {
  return (
    <div>
      <h1>Protected Page</h1>
    </div>
  );
}
export async function getServerSideProps(context) {
  const session = await getSession(context);
  if (!session) {
    context.res.writeHead(302, { Location: "/" });
    context.res.end();
    return {};
  }
  return {
    props: {
      user: session.user,
    },
  };
}
export default protectedpage;

The code above uses a function to check if Session exists to allow access to the page. If Session does not exist, the user will be redirected to the "``/``" route which is the home page of the application.

We can set up the redirect page called user.js with the following code:

import React from "react";
import { useSession } from "next-auth/react";
function user() {
  const { data: session } = useSession();
  if (!session) {
    return <p>You are not logged in.</p>;
  }
  return <h1>you are logged in</h1>;
}
export default user;

Then in the protectedpage.js file, we can set the header location to return us to the redirect page instead of the home page:

...
context.res.writeHead(302, { Location: "/user" });
...

Conclusion

We have come to the end of this tutorial where we learned how to integrate the Next-authentication package and make use of Google’s main login in a Next application.