Select Page

How to implement Social Login in Nextjs (React) using NextAuth

Rahul Chaudhary
Published: February 14, 2023

In this blog, we will discuss how to implement Social Login in Nextjs (React) using NextAuth for your apps.

What is Next.js?

Next.js is a flexible React framework that gives you building blocks to create fast web applications.

Next.js is a framework built on top of React that makes developing production-ready, fully-optimized React apps super fast and easy. It is one of the best things to have come out of the React ecosystem, as it comes with a whole lot of power with zero config.

What is NextAuth?

NextAuth.js is a completely secured authentication for implementation in Next.js applications. It is a flexible authentication library designed to sync with any OAuth service.

When you need to add authentication to your next.js project, NextAuth is a wonderful option. It’s easy to see why, given its extensive provider support, which includes Google, Facebook, Credentials, and more. It can help you set up your authentication in minutes!

Let’s create NextApp.

To create the next app visit here: How to Create Next App

Set up authentication with NextAuth.js

After the installation of the next application, we’re ready to learn how to authenticate a Next.js app with NextAuth.js.

Now let’s install the NextAuth package by running the below command.

npm i next-auth

We’re going to provide customers the selection to log in to our app using their Google, or Facebook

Facebook

To use the Facebook login for our app, we are able to need a Facebook developer account. Create an account after which create your app. For the app type, pick Cusumer

SelectType
App Type

Click next and within the details screen, pick a display name.

Once this is completed, your screen has to appear like this:

Click on Facebook Login and select Web. Now, add the following:

AddWebUrl
Web URL

To get your app ID and app secret, navigate to the Basic section in Settings and copy them.

App-Creds
App I
App-Creds
App ID and Secret

Add http://localhost:3000/ in the App Domains field.

Add an environmental variable

Next, create an .env.local file in your project’s root directory. Next.js has inbuilt support for environment variables and .env.local will load those variables to process.env. Therefore, the filename cannot be a random name. For more information, please read Next.js documentation on environment variables.

Next, populate it with the following content:

FACEBOOK_ID=<app id of your facebook app>
FACEBOOK_SECRET=<app secret of your facebook app>
NEXTAUTH_URL=http://localhost:3000

Now, returned to our app. We’re going to create a file named […nextauth].js in pages/api/auth and add the following code:

import NextAuth from 'next-auth';
import FacebookProvider from 'next-auth/providers/facebook';
const options = {
    providers: [
        FacebookProvider({
          clientId: process.env.FACEBOOK_ID,
          clientSecret: process.env.FACEBOOK_SECRET
        }),
    ],
}
export default (req, res) => NextAuth(req, res, options)

At Line 1, We are importing our main package (NextAuth). On line 2, we’re importing our Facebook Providers from the next-auth library, which are services that we can integrate into our app to allow users to sign in.

At Line 6, we’re configuring our Facebook provider and passing in our Facebook secret and client ID through our environmental variables. Finally, on line 13, we’re exporting a function that returns the NextAuth and takes in the options variable as a third parameter.

Properly, the magic has befallen already. If we make use of the REST API provided by next-auth, we can log in to our app using our Facebook account. Navigate to http://localhost:3000/api/auth/signin and you should see this 

sign-in
Sign In

Follow the process. You are logged in. Now, we need to save and display the user login state.

Check user login state with the useSession() Hook

We need to get the login state of our users and render user details on the front end of our app. This can be easily achieved by using a Next.js feature called custom app. Then, we’ll wrap our component in a Provider.

Create an _app.js file in your pages directory (if it doesn’t already exist) and add the following code:

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

By wrapping our components in a Session``Provider, we enable session state to be shared between pages. This, in turn, will preserve our state during page navigation, improve performance, and reduce network traffic.

Next, create the components/Header.js file and import useSessionsignIn, and signOut from next-auth/client:

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

useSession will be used to manage the sign in and sign out state of our users, while signIn and signOut will be used to perform the login and logout features in our app.

Let’s make use of the useSession Hook:

const { data: session } = useSession();

The session will return the user’s details. Let’s use the details returned to conditionally render a sign in and sign out button.

Replace everything in the return statement in components/Header.js with the following code:

<div className="header">
      {session ? (
        <a href="#" onClick={handleSignout} className="btn-signin">
          <button>Sign out</button>
        </a>
      ) : (
        <a href="#" onClick={handleSignin} className="btn-signin">
          <button> Sign in</button>
        </a>
      )}
</div>

We need to create the handleSignin and handleSignout methods to enable our users to sign in and sign out:

const handleSignin = (e) => {
    e.preventDefault();
    signIn();
  };
  const handleSignout = (e) => {
    e.preventDefault();
    signOut();
  };

Your Header.js should now look like this:

import { useSession, signIn, signOut } from 'next-auth/react'
export default function Header () {
  const { data: session } = useSession();
  const handleSignin = (e) => {
    e.preventDefault();
    signIn();
  };
  const handleSignout = (e) => {
    e.preventDefault();
    signOut();
  };
  return (
    <div className="header">
      {session ? (
        <a href="#" onClick={handleSignout} className="btn-signin">
          <button>Sign out</button>
        </a>
      ) : (
        <a href="#" onClick={handleSignin} className="btn-signin">
          <button> Sign in</button>
        </a>
      )}
    </div>
  )
}

Feel free to sign in and sign out of the app using the header button.

Retrieve and display user information

Now, onto our pages/index.js. We need to display and conditionally render user details based on their login details. First, we have to import the useSession hook from next-auth.

So, replace your index.js with the following content:

import Head from "next/head";
import Header from "../components/Header";
import styles from "../styles/Home.module.css";
import { useSession } from "next-auth/react";
export default function Home() {
  const { data: session, status } = useSession();
  const loading = status === "loading";
  return (
    <div className={styles.container}>
      <Head>
        <title>Nextjs | Next-Auth</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <Header />
      <main className={styles.main}>
        <h1 className={styles.title}>
          Authentication in Next.js app using Next-Auth
        </h1>
        <div className={styles.user}>
          {loading && <div className={styles.title}>Loading...</div>}
          {session ? (
            <>
              <p style={{ marginBottom: "10px" }}>
                Welcome, {session.user.name ?? session.user.email}
              </p>
              <br />
              <img src={session.user.image} alt="" className={styles.avatar} />
            </>
          ) : (
            <p className={styles.title}>Please Sign in</p>
          )}
        </div>
      </main>
    </div>
  );
}

In this code, we are conditionally rendering the user’s image, name, and photo using the data from our session state if the user is logged into our app. If the user is not logged in, we display a dummy GIF with text instructing them to sign in.

SignIn
Welcome

Google

To allow users to log in to our app using their Google account, we have to obtain OAuth 2.0 client credentials from the Google API Console. Navigate to Credentials and click on Create credentials, and then OAuth client ID:

google-create-api
Create a Google OAuth client ID.

Fill in the following options as asked:

  • Choose an Application Type: Select Web Application
  • Name: This is the name of your application
  • Authorized JavaScript origins: This is the full URL to the homepage of our app. Since we are still in development mode, we are going to fill in the full URL our development server is running on. In this case, it is http://localhost:3000
  • Authorized redirect URIs: Redirected to this route after customers will authenticated with Google: http://localhost:3000/api/auth/callback/google

Next, a popup will display your client ID and client secret.

OAuthGoogle
Created Google OAuth client ID and secret ID.

Copy and add them to your env.local file:

GOOGLE_ID=<client id of your google auth app should go in here>
GOOGLE_SECRET=<client secret of your google auth app should go in here>

Next, navigate to pages/api/auth/[...nextauth].js and add the following to your array of providers:

import GoogleProvider from 'next-auth/providers/google';
...
   GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
    }),
...

Your [...nextauth].js should now look like this:

import NextAuth from "next-auth";
import FacebookProvider from "next-auth/providers/facebook";
import GoogleProvider from 'next-auth/providers/google';
const options = {
  providers: [
    FacebookProvider({
      clientId: process.env.FACEBOOK_ID,
      clientSecret: process.env.FACEBOOK_SECRET,
    }),
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
    }),
  ],
};
export default (req, res) => NextAuth(req, res, options);

To test out user login using a Google account, quit your development server and run npm run dev.
Now, with our fingers crossed and our heads held high, we should be able to sign in to our app with our Google account:

SignInWithGoogle
Sign in with Google.

After you restart your development server, customers should be capable of logging in on your Next.js app with the use of their Google, and Facebook accounts.

That’s all about the Social Login with NextAuth. If you have any questions please comment below, and we will try to respond to you.

To implement authentication in Nextjs with Magento 2 using the NextAuth credentials provider, check out our previous blog: Click Here

Happy coding 🙂

Source: webkul.com