Implementing OAuth Authentication in Next.js

Introduction

OAuth allows users to log in via third-party providers like Google and GitHub. Here’s a streamlined guide to integrating OAuth with NextAuth.js in your Next.js application.

Setup
 

Initialize Project

Create a Next.js app if you don’t have one.

npx create-next-app@latest my-next-app
cd my-next-app

Install Dependencies

Install next-auth

npm install next-auth

Configure OAuth Providers
 

Obtain Credentials

Register your app with OAuth providers (e.g., Google, GitHub) to get Client ID and Client Secret.

Configure NextAuth

Create pages/api/auth/[...nextauth].js

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

export default NextAuth({
  providers: [
    Providers.Google({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
    Providers.GitHub({
      clientId: process.env.GITHUB_CLIENT_ID,
      clientSecret: process.env.GITHUB_CLIENT_SECRET,
    }),
    // Additional providers here
  ],
  session: { jwt: true },
  callbacks: {
    async jwt(token, user) {
      if (user) {
        token.id = user.id;
        token.email = user.email;
      }
      return token;
    },
    async session(session, token) {
      session.user.id = token.id;
      session.user.email = token.email;
      return session;
    },
  },
});

Environment Variables

Update .env.local

GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret

Create Authentication Pages
 

Sign-In Page

Create pages/signin.js

// pages/signin.js
import { signIn } from 'next-auth/react';
export default function SignIn() {
  return (
    <div>
      <h1>Sign In</h1>
      <button onClick={() => signIn('google')}>
        Sign in with Google
      </button>
      <button onClick={() => signIn('github')}>
        Sign in with GitHub
      </button>
    </div>
  );
}

Sign-Out Page

Create pages/signout.js

// pages/signout.js
import { signOut } from 'next-auth/react';
export default function SignOut() {
  return (
    <div>
      <h1>Sign Out</h1>
      <button onClick={() => signOut()}>Sign out</button>
    </div>
  );
}

Protect Routes
 

Server-Side Protection

Use getServerSideProps for server-side authentication.

// pages/protected.js
import { getSession } from 'next-auth/react';
export default function ProtectedPage() {
  return <div>This is a protected page.</div>;
}

export async function getServerSideProps(context) {
  const session = await getSession(context);

  if (!session) {
    return { redirect: { destination: '/signin', permanent: false } };
  }

  return { props: { session } };
}

Client-Side Protection

Protect client-side components.

// components/ProtectedComponent.js
import { useSession } from 'next-auth/react';

export default function ProtectedComponent() {
  const { data: session, status } = useSession();

  if (status === 'loading') return <p>Loading...</p>;
  if (!session) return <p>You must be logged in to view this content.</p>;

  return <div>Welcome, {session.user.email}!</div>;
}

Handle Redirects

Customize redirects in pages/api/auth/[...nextauth].js.

// pages/api/auth/[...nextauth].js
export default NextAuth({
  // Other configurations...
  pages: {
    signIn: '/signin',
    signOut: '/signout',
    error: '/error',
    verifyRequest: '/verify-request',
  },
});

Testing
 

Run Your App

npm run dev

Test Authentication

Visit http://localhost:3000/signin to test OAuth sign-in.

Best Practices

  • Secure Credentials: Keep OAuth credentials safe.
  • Handle Tokens: Configure token expiration and refresh as needed.
  • Use HTTPS: Ensure secure data transmission.
  • Error Handling: Provide clear error messages for failed authentication.

Summary

OAuth authentication with NextAuth.js simplifies integrating third-party login options in a Next.js app. Configure providers, create authentication pages, and protect routes to offer a secure and user-friendly login experience.