TrueSpec

Next.js Google OAuth Login

Complete Google OAuth flow with NextAuth.js, token handling, session management

What You’ll Build

After following this guide, you will have a working implementation of next.js google oauth login in your project. Add Google sign-in to your Next.js app using NextAuth.js. This handles the full OAuth 2.0 authorization code flow, secure session management with JWTs or database sessions, and automatic token refresh. Works with both Pages Router and App Router.

Use Cases & Problems Solved

  • Protect routes so only authenticated users can access sensitive pages
  • Allow users to sign up, log in, and manage their accounts securely
  • Avoid storing raw passwords or building session management from scratch

Prerequisites

  • Node.js 18+
  • Google Cloud Console project with OAuth 2.0 credentials
  • Next.js 13+ project

Step-by-Step Implementation

Install NextAuth.js

The following snippet shows how to install nextauth.js. Copy this into your project and adjust the values for your environment.

npm install next-auth

Create the API route

Create pages/api/auth/[...nextauth].js (Pages Router) or app/api/auth/[...nextauth]/route.js (App Router).

// pages/api/auth/[...nextauth].js
import NextAuth from 'next-auth';
import GoogleProvider from 'next-auth/providers/google';

export default NextAuth({
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
  ],
  secret: process.env.NEXTAUTH_SECRET,
});

Add SessionProvider to _app.js

The following snippet shows how to add sessionprovider to _app.js. Copy this into your project and adjust the values for your environment.

// pages/_app.js
import { SessionProvider } from 'next-auth/react';

export default function App({ Component, pageProps: { session, ...pageProps } }) {
  return (
    <SessionProvider session={session}>
      <Component {...pageProps} />
    </SessionProvider>
  );
}

Protect a page with useSession

The following snippet shows how to protect a page with usesession. Copy this into your project and adjust the values for your environment.

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

export default function Dashboard() {
  const { data: session, status } = useSession();
  if (status === 'loading') return <p>Loading...</p>;
  if (!session) return <button onClick={() => signIn('google')}>Sign In</button>;
  return (
    <div>
      <p>Welcome, {session.user.name}</p>
      <button onClick={() => signOut()}>Sign Out</button>
    </div>
  );
}

⚠️ Don’t Do This

❌ Hardcoding secrets in source code

// DO NOT commit secrets to git!
const authOptions = {
  providers: [GoogleProvider({
    clientId: 'YOUR_ID_HERE.apps.googleusercontent.com',
    clientSecret: 'GOCSPX-hardcoded-secret-value',
  })],
};

✅ Use environment variables in .env.local

# .env.local (never committed to git)
GOOGLE_CLIENT_ID=your-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-your-secret
NEXTAUTH_SECRET=run-openssl-rand-base64-32

Testing

Add these tests to verify your next.js google oauth login implementation works correctly:

// __tests__/next.js.test.ts
import { describe, it, expect } from 'vitest';

describe('Next.js Google OAuth Login', () => {
  it('should handle successful authentication', async () => {
    // Test the happy path
    const result = await authenticate({ email: 'test@example.com', password: 'valid' });
    expect(result.user).toBeDefined();
    expect(result.error).toBeNull();
  });

  it('should reject invalid credentials', async () => {
    const result = await authenticate({ email: 'test@example.com', password: 'wrong' });
    expect(result.user).toBeNull();
    expect(result.error).toBeDefined();
  });

  it('should handle missing fields', async () => {
    const result = await authenticate({ email: '', password: '' });
    expect(result.error).toBeDefined();
  });
});

Verification

npm run dev
# Visit http://localhost:3000/api/auth/signin
# Click 'Sign in with Google' and complete the flow
# Verify session is created and user info displays

Related Specs

Intermediate

GitHub OAuth with FastAPI

OAuth2 Authorization Code flow with token exchange and user profile fetch

Auth & Identity
Beginner

Clerk Auth in Next.js App Router

Drop-in auth with Clerk, middleware protection, and user metadata

Auth & Identity
Beginner

Firebase Auth with React

Google/GitHub sign-in, onAuthStateChanged listener, and route protection

Auth & Identity