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
GitHub OAuth with FastAPI
OAuth2 Authorization Code flow with token exchange and user profile fetch
Clerk Auth in Next.js App Router
Drop-in auth with Clerk, middleware protection, and user metadata
Firebase Auth with React
Google/GitHub sign-in, onAuthStateChanged listener, and route protection