nextjs login oauth bannerEngineering

How to implement Social Login (OAuth) in Next.js

Learn how to implement a Next.js login page with Social Login (OAuth), in this tutorial.

Blog-Post-Author

Vincent

Created: December 17, 2024

Updated: December 17, 2024


Our mission is to make the Internet a safer place, and the new login standard passkeys provides a superior solution to achieve that. That's why we want to help you understand passkeys and its characteristics better.

1. Introduction#

Next.js is a powerful framework that allows developers to build fast and user-friendly web applications. One of the most critical aspects of any web application is user authentication.

In this guide, we'll walk you through the process of implementing a login page in Next.js, with Social Login (OAuth).

If you want to see the complete code and check out other authenciation methods (OTP, passkeys, authenticator app), use our Next.js login page repository on GitHub. There you will find information regarding:

  • Password-based authentication
  • Email OTP (one-time passcode)
  • SMS OTP (one-time passcode)
  • Social login (OAuth)
  • TOTP (via authenticator app)
  • Passkeys

2. Setting Up Your Next.js Project#

Before we jump into the One-Time Password (OTP) authentication, we need to perform some general project setup steps.

Substack Icon

Subscribe to our Passkeys Substack for the latest news, insights and strategies.

Subscribe

2.1 Prerequisites#

To follow this guide, we require some basic understanding of

  • Next.js
  • React
  • JavaScript
  • TypeScript
  • Node.js
  • NPM
  • HTML
  • MongoDB

2.2 Create a New Next.js Project#

Open your terminal and run the following command to create a new Next.js project:

npx create-next-app@latest nextjs-auth-methods

In the installation guide steps, we select the following:

  • TypeScript: Yes
  • ESLint: Yes
  • Tailwind CSS: Yes
  • src/ directory: Yes
  • App Router: Yes
  • Default import alias: No

Navigate to your project directory:

cd nextjs-login

2.3 Start the Development Server#

To verify that your Next.js project is set up correctly, start the development server:

npm run dev

Open your browser and navigate to http://localhost:3000. You should see the default Next.js welcome page.

2.4 Set Up Environment Variables#

Create a .env.local file in the root of your project to store environment variables. Add your variables here:

MONGODB_URI=your_database_connection_string GOOGLE_CLIENT_ID=your_google_client_id GOOGLE_CLIENT_SECRET=your_google_client_secret TWILIO_ACCOUNT_SID=your_twilio_account_sid TWILIO_AUTH_TOKEN=your_twilio_auth_token TWILIO_PHONE_NUMBER=your_twilio_phone_number
Slack Icon

Become part of our Passkeys Community for updates and support.

Join

3. Social login (OAuth)#

Using OAuth for third-party authentication is a very popular and user-friendly solution. In this section, we'll explore how to integrate Google authentication into a Next.js application using NextAuth.js.

We chose NextAuth.js for Google authentication because it's easy to integrate and offers robust security features. NextAuth.js simplifies adding Google OAuth, providing a seamless and secure login experience. It handles the complex parts of authentication, so we can focus on building our app. Plus, it's highly customizable, making it a perfect fit for our needs.

Google social login interfaceGoogle social login interface

The following steps covers the implementation of the Google authentication:

  1. Set Up Google-Based Authentication Project
  2. Google Cloud Setup for OAuth 2.0 Credentials
  3. Installing the Relevant Dependencies
  4. Configuring NextAuth.js
  5. Creating Authentication Components 5.1 Creating SignInButton Component 5.2 Creating LogoutButton Component 5.3 Creating ClientProvider Component
  6. Creating Google Authentication Page
  7. Testing the Google Authentication Flow

3.1 Set Up Google-Based Authentication Project#

In this section, we'll detail how to set up Google-based authentication (Google social login) for your Next.js project. We'll break down the specific files and structure. Let's start with an overview of the relevant directory structure and the key files involved:

Key Files and Their Roles:

  • .env.local: In this file will store the environment variables which are your Google client ID GOOGLE_CLIENT_ID and secret GOOGLE_CLIENT_SECRET
  • src/pages/api/auth/[...nextauth].ts: This file sets up NextAuth.js for handling authentication. It includes configuration for Google as an authentication provider.
  • src/components/ClientProvider.tsx: A wrapper component that provides session management using NextAuth.js. It ensures that session data is available throughout your application.
  • src/app/layout.tsx: The root layout for your application, which wraps all pages with the ClientProvider to manage session state globally.
  • src/components/SignInButton.tsx: A component that renders a button for signing in with Google. It handles the sign-in process when clicked.
  • src/components/LogoutButton.tsx: A component that renders a logout button. It handles signing the user out and redirecting them appropriately.
  • src/app/googleLogin/page.tsx: The main page for handling Google login. It displays different content based on whether the user is signed in or not.

3.2 Google Cloud Setup for OAuth 2.0 Credentials#

  1. Create a New Project in Google Cloud Console

Create New Project screen on Google Console

  • Enter a project name and click "Create". Project creation screen on Google Console
  1. Configure our OAuth Consent Screen
    • Once your project is created, navigate to the "OAuth Consent Screen" section. First step of the OAuth consent screen
    • Select External users
    • Add the app name, select the user support email and add the developer contact information

App Information section on the OAuth consent screen

App Domain and Developer Contact Info consent screen

  1. Create OAuth 2.0 Credentials
    • In the "APIs & Services" section, click on "Credentials" in the left sidebar.
    • Click on "Create Credentials" and select "OAuth 2.0 Client ID".

Create credentials screen on Google Cloud Console

  • You may be prompted to configure the OAuth consent screen if you haven't done so already.
  • Click on "OAuth consent screen" and fill out the required fields.

Configure consent screen

  • After configuring the consent screen, choose "Web application" as the application type.

App type interface on Google Console

  • Enter a name for the OAuth client and add your application's URLs in the "Authorized redirect URIs" field. Typically, this would be something like http://localhost:3000/api/auth/callback/google for local development. Google Cloud App credentials
  • Click "Create" and note down your Client ID and Client Secret.
  1. Add Credentials to .env.local
    • Open your .env.local file and add the following environment variables:
GOOGLE_CLIENT_ID=<YOUR_GOOGLE_CLIENT_ID> GOOGLE_CLIENT_SECRET=<YOUR_GOOGLE_CLIENT_SECRET>

3.3 Installing the Relevant Dependencies#

First, install the necessary dependencies:

  • NextAuth.js: A complete open-source authentication solution for Next.js applications. It supports various authentication methods, including OAuth providers like Google, GitHub, Twitter, and more.
  • react-icons: A popular library for including icons in your React application. We'll use it to enhance the UI of the sign in button by adding a Google icon.

You can install the dependencies using the following command:

npm install next-auth react-icons

3.4 Configuring NextAuth.js#

In this section, we will configure NextAuth.js to handle Google authentication in our Next.js application. We will walk through the specific file used for this configuration, its location, purpose, and explain the main concepts involved. Additionally, we’ll discuss the reason behind the file naming convention [...nextauth].

Good to know: Reason for the Naming Convention [...nextauth]

The file is named [...nextauth].ts to leverage Next.js's dynamic routing feature. The square brackets [ ] denote a dynamic route segment, and the three dots ... indicate a catch-all route. This means that any API route starting with /api/auth/ (e.g., /api/auth/signin, /api/auth/signout, /api/auth/callback) will be handled by this file. This naming convention provides a flexible way to manage all authentication-related routes in a single file.

  1. File Location: Create a new file at src/pages/api/auth/[...nextauth].ts in your project directory
  2. Purpose: This file sets up and configures NextAuth.js to handle authentication using Google provider. It also includes callback functions to manage user sessions.
  3. Explanation
    • Import Statements:
      • NextAuth: The core module for handling authentication in Next.js.
      • GoogleProvider: A provider module for handling Google OAuth authentication.
    • Session Interface: Session: An interface to type the user data returned in the session object. It ensures that the session contains a user object with name and email properties.
    • NextAuth Configuration:
      • providers: This array contains authentication providers. Here, we configure Google as the provider using the GoogleProvider module. The clientId and clientSecret are fetched from environment variables to ensure they are not hardcoded and remain secure.
      • callbacks: This object contains the session function called during the authentication process. The session function is called whenever a session is checked or created. It modifies the session object to include the user's name and email from the token.

Here’s the complete code of the [...nextauth].ts file:

import NextAuth from 'next-auth'; import GoogleProvider from 'next-auth/providers/google'; // Define the Session interface to type the user data export interface Session { user: { name: string | null; email: string | null; }; } export default NextAuth({ // Define the authentication providers providers: [ GoogleProvider({ // Set the Google client ID and client secret from environment variables clientId: process.env.GOOGLE_CLIENT_ID || '', clientSecret: process.env.GOOGLE_CLIENT_SECRET || '', }), ], // Define callback functions to manage session and token callbacks: { // Modify the session object before it is returned to the client async session({ session, token }) { // Ensure the session user object exists and set name and email from token if (session.user) { session.user.name = token.name || null; session.user.email = token.email || null; } return session; }, }, });

3.5 Creating Authentication Components#

In this section, we'll create the essential components needed for handling authentication in our Next.js application. These components include a sign-in button for Google authentication and a logout button for signing out. We'll also create a client provider to manage session state across the application.

Here are the components we'll create:

  • 7.5.1 SignInButton.tsx
  • 7.5.2 LogoutButton.tsx
  • 7.5.3 ClientProvider.tsx

These components will be placed in the src/components directory. Each of these components serves a specific purpose in the authentication flow.

3.5.1 Creating SignInButton Component#

  1. File Location: create a new file at src/components/SignInButton.tsx
  2. Purpose: This component renders a button that allows users to sign in with their Google account.
  3. Explanation:
    • signIn function: From next-auth/react, it handles the sign-in process with Google.
    • Button Element: Triggers the signIn function with Google as the provider and includes the prompt: "select_account" parameter to ensure the account chooser appears.

Here’s the complete code of the SignInButton.tsx file:

"use client"; import { signIn } from "next-auth/react"; import { FaGoogle } from "react-icons/fa"; function SignInButton() { return ( <button onClick={() => signIn("google", { prompt: "select_account" })} className="flex items-center justify-center px-4 py-2 rounded border-gray-900 border hover:bg-blue-100" > <FaGoogle className="mr-2" /> Sign in with Google </button> ); } export default SignInButton;

3.5.2 Creating LogoutButton Component#

  1. File Location: create a new file atsrc/components/LogoutButton.tsx
  2. Purpose: This component renders a button that allows users to sign out of their account.
  3. Explanation:
    • signOut function: From next-auth/react, it handles the sign-out process.
    • Button Element: Triggers the signOut function and redirects the user to the /googleLogin page after signing out.

Here’s the complete code of the LogoutButton.tsx file:

"use client"; import { signOut } from "next-auth/react"; function LogoutButton() { return ( <button onClick={() => signOut({ callbackUrl: "/googleLogin" })} className="px-4 py-2 bg-blue-300 rounded hover:bg-blue-400" > Logout </button> ); } export default LogoutButton;

3.5.3 Creating ClientProvider Component#

  1. File Location: create a new file at src/components/ClientProvider.tsx
  2. Purpose: This component wraps the application with the SessionProvider to manage session state globally.
  3. Explanation:
    • Props Interface: Defines the type for the component's props to ensure it receives children as a React node.
    • SessionProvider: From next-auth/react, it wraps the children components to provide session management.

Here’s the complete code of the ClientProvider.tsx file:

"use client"; import { SessionProvider } from "next-auth/react"; import { ReactNode } from "react"; // Define a type for the component's props interface Props { children: ReactNode; } const ClientProvider = ({ children }: Props) => { return ( // Wrap the children with the SessionProvider to manage session state <SessionProvider>{children}</SessionProvider> ); }; export default ClientProvider;

3.6 Configuring the Root Layout#

In this section, we'll configure the root layout of your Next.js application to ensure that session state is managed globally. This involves using the ClientProvider component, which wraps the entire application and provides session management using NextAuth.js.

  1. File Location: src/app/layout.tsx
  2. Purpose: This file sets up the root layout for your Next.js application. It ensures that all pages are wrapped with the ClientProvider, enabling global session management.
  3. Explanation:
    • Props:
      • children: The children prop represents all the child components that will be wrapped by this layout. This includes all the pages and components in your application.
      • <ClientProvider>: Wraps the children components with the ClientProvider to manage session state globally. This ensures that session information is accessible across all pages and components in your application.

Here’s the complete code of the layout.tsx file:

import "./globals.css"; import ClientProvider from "@/components/ClientProvider"; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <body> {/* Wrap the children with ClientProvider to manage session state */} <ClientProvider>{children}</ClientProvider> </body> </html> ); }

3.7 Creating Google Authentication Page#

In this section, we will focus on how to handle user sign-in and sign-out actions on the main login page. We will use the previously created SignInButton and LogoutButton components and ensure they are integrated seamlessly with our authentication flow.

  1. File Location: create a new file at src/app/googleLogin/page.tsx
  2. Purpose: This file represents the main page for handling Google login. It displays different content based on whether the user is signed in or not.
  3. Explanation:
  • Import Statements:
    • useSession: A hook from next-auth/react that provides session information.
      • SignInButton: The sign-in button component created earlier.
      • LogoutButton: The logout button component created earlier.
    • Session Handling:
      • The useSession hook fetches the current session data.
      • If a session exists (i.e., the user is logged in), it displays a welcome message and the LogoutButton.
      • If no session exists (i.e., the user is not logged in), it displays the SignInButton.

Here’s the complete code of the page.tsx file:

"use client"; import { useSession } from "next-auth/react"; import SignInButton from "../../components/SignInButton"; import LogoutButton from "../../components/LogoutButton"; function GoogleLoginPage() { const { data: session } = useSession(); if (session) { return ( <div className="flex items-center justify-center min-h-screen bg-gray-100"> <div className="bg-white p-6 rounded-lg shadow-md text-center"> <h1 className="text-2xl font-semibold mb-4"> Welcome, {session.user?.name}! </h1> <LogoutButton /> </div> </div> ); } return ( <div className="flex items-center justify-center min-h-screen bg-gray-100"> <div className="bg-white p-6 rounded-lg shadow-md text-center"> <h1 className="text-2xl font-semibold mb-4">Social Login</h1> <SignInButton /> </div> </div> ); } export default GoogleLoginPage;

3.8 Testing the Google Authentication Flow#

By following these steps, you can test the Google authentication flow in your Next.js application. Ensure that each step works correctly:

  • Route: http://localhost:3000/googleLogin
  • Steps:
  1. Open your browser and navigate to the login page http://localhost:3000/googleLogin. You should see the Google Sign-In button.

Google social login interfaceGoogle social login interface

  1. Click on the Sign in with Google button. This action should redirect you to Google's authentication page.
  2. On the Google authentication page, sign in with your Google account Google Account sign-in page

Consent screen for Google Auth 4. After signing in, you should be redirected back to your application. If the sign-in was successful, you should see a welcome message along with the Logout button.

Welcome interface for Google Auth

By following these steps, you will have successfully set up Google authentication in your Next.js application using NextAuth.js. This setup includes creating necessary components, configuring authentication providers, and managing session states.

4. Recommendation for Next.js Authentication & Login Pages#

Event though we just looked at how to roll out OAuth authencication, which is not the safest auth method, building a secure and user-friendly authentication system is crucial to protect user data and provide a great first impression of your app. Authentication is often the first interaction a user has with your product and the first thing they will complain about if something goes wrong. Besides the detailed steps laid out above, we also have some additional best practices for Next.js authentication and login pages:

  • Don’t Roll out Your Own Auth: Use libraries and packages for tested security solutions and to save implementation time. Libraries like NextAuth.js or Auth0 are excellent choices as they offer robust and secure authentication solutions out of the box.
  • Implement Multi-Factor Authentication (MFA): Combine authentication methods to achieve MFA, e.g., password plus TOTP to add an extra layer of security.
  • Validate Email Addresses: Use APIs to check if email addresses are valid and belong to real users. Avoid allowing one-time or disposable email addresses to prevent spam and ensure genuine user engagement.
  • Prevent SMS Pumping Attacks: Implement rate limits on SMS verifications and restrict access to certain areas to prevent SMS pumping attacks. Use services that can help identify and block fraudulent requests.
  • Limit Login Attempts: To prevent brute force attacks, implement rate limiting on authentication routes. Temporarily block IP addresses after a set number of failed login attempts to protect against automated attacks.
  • Never Store Passwords in Plain Text: Ensure that passwords are stored securely using hashing algorithms like bcrypt. Never store passwords in plain text.
  • Implement Proper Session Management: Authentication is only the first step. After successfully authenticating your users, ensure you have proper session management in place to prevent session hijacking.
  • Use HTTPS Everywhere: Always use HTTPS to encrypt data in transit. This protects user credentials and other sensitive data from being intercepted by attackers.
  • Monitor and Log Authentication Events: Keep track of authentication events and monitor them for suspicious activities. Implement logging and alerting to quickly detect and respond to potential security threats.

By following these practices, you'll keep your application robust against common threats and ensure a safe environment for your users. Secure authentication not only protects your users but also builds trust and credibility for your application.

7. Conclusion#

In this Next.js login page guide, we explored various authentication methods to secure your Next.js applications. Here’s a recap of what we covered:

  • Social login (OAuth): We set up Google-based authentication using NextAuth.js, configured Google Cloud for OAuth 2.0 credentials, and created components for signing in and out.

Choosing the right authentication method for your application depends on various factors, including security requirements, user convenience, and the nature of your application. Each method we covered has its strengths and can be used alone or in combination to provide a robust authentication system. Experiment with different methods, gather user feedback, and iterate on your implementation to achieve the best balance for your specific needs.

Share this article


LinkedInTwitterFacebook

Enjoyed this read?

🤝 Join our Passkeys Community

Share passkeys implementation tips and get support to free the world from passwords.

🚀 Subscribe to Substack

Get the latest news, strategies, and insights about passkeys sent straight to your inbox.


We provide UI components, SDKs and guides to help you add passkeys to your app in <1 hour

Start for free