Google Provider

Configure Google OAuth for authentication in your Next.js application using NextAuth.js.

Documentation

https://developers.google.com/identity/protocols/oauth2

Configuration

https://console.developers.google.com/apis/credentials

Google Console Setup

Follow these steps to configure Google OAuth:

Step 1: Create a Google Cloud Project

  1. Go to Google Cloud Console
  2. Click on the project dropdown at the top
  3. Click "New Project"
  4. Enter a project name and click "Create"

Step 2: Configure OAuth Consent Screen

  1. Navigate to APIs & Services → OAuth consent screen
  2. Select External user type (or Internal for Google Workspace)
  3. Fill in the required fields:
FieldValue
App nameYour application name
User support emailYour email address
Developer contact informationYour email address
  1. Add scopes: email, profile, openid
  2. Save and continue

Step 3: Create OAuth Credentials

  1. Navigate to APIs & Services → Credentials
  2. Click + CREATE CREDENTIALS → OAuth client ID
  3. Select Web application as the application type
  4. Enter a name for your OAuth client
  5. Add Authorized JavaScript origins:
EnvironmentURI
Developmenthttp://localhost:3000
Productionhttps://your-domain.com

Step 4: Add Authorized Redirect URIs

The "Authorized redirect URIs" used when creating the credentials must include your full domain and end in the callback path:

EnvironmentRedirect URI
Developmenthttp://localhost:3000/api/auth/callback/google
Productionhttps://YOUR_DOMAIN/api/auth/callback/google

Step 5: Get Client ID and Secret

  1. After creating, copy the Client ID and Client Secret
  2. Add them to your .env.local file:
# .env.local
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret

Options

The Google Provider comes with a set of default options. You can override any of the options to suit your own use case.

Google Provider options →

Example

// src/core/lib/auth.ts
import GoogleProvider from "next-auth/providers/google";

export const authOptions: NextAuthOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
  ],
};

Warning

Google only provides Refresh Token to an application the first time a user signs in.

To force Google to re-issue a Refresh Token, the user needs to remove the application from their account and sign in again: https://myaccount.google.com/permissions

Force Refresh Token

Alternatively, you can pass options in the params object of authorization which will force the Refresh Token to always be provided on sign in. However, this will ask all users to confirm if they wish to grant your application access every time they sign in.

If you need access to the RefreshToken or AccessToken for a Google account and you are not using a database to persist user accounts, this may be something you need to do.

// src/core/lib/auth.ts
import GoogleProvider from "next-auth/providers/google";

export const authOptions: NextAuthOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
      authorization: {
        params: {
          prompt: "consent",
          access_type: "offline",
          response_type: "code",
        },
      },
    }),
  ],
};

Tip

Google also returns a email_verified boolean property in the OAuth profile.

You can use this property to restrict access to people with verified accounts at a particular domain.

Restrict to Verified Domain

// src/core/lib/auth.ts
export const authOptions: NextAuthOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
  ],
  callbacks: {
    async signIn({ account, profile }) {
      if (account?.provider === "google") {
        const googleProfile = profile as { email_verified?: boolean; email?: string };
        return (
          googleProfile.email_verified === true &&
          googleProfile.email?.endsWith("@example.com") === true
        );
      }
      return true;
    },
  },
};

Troubleshooting

Common Errors

ErrorSolution
redirect_uri_mismatchCheck that your redirect URI exactly matches the one in Google Console
Access blocked: App not verifiedSubmit your app for verification or add test users in OAuth consent screen
Invalid client_idVerify GOOGLE_CLIENT_ID is correctly set in .env.local