Concept Welder

"Where new ideas are forged and brought to life"
OAuth in Next.js using Auth.js | Concept Welder

OAuth in Next.js using Auth.js

When you need to register on a new platform, what’s your preferred way? Do you fill out a lengthy form, validate your email, create a strong password, and then manage that password? Or do you simply log in using your social media account or another OAuth provider?

Most likely, you opt for the convenience of an OAuth provider. But how do you implement this in a Next.js application? Follow this step-by-step guide to seamlessly integrate OAuth with Next js using Auth.js.

1. Let’s start with new Next.js App

I used Create Next App CLI tool.

 npx create-next-app@latest
 # with 
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev

Basic Next.js app running.

Step 1 source

2. Install and setup Auth.js

Although it’s still in beta, that’s okay! After installing the npm package, you’ll need to generate an auth secret and configure it in the .env file

 # to install pacakge
npm install next-auth@beta

# go generate auth secreat key
npx auth secret

3. Setup Auth configuration file and API files.

You’ll need to create two files to hold configuration information and handle the API. Respectively, create the auth.ts file for configuration and the api/auth/[...nextauth]/route.ts file for the API.

 // auth.ts
import NextAuth from "next-auth"
 
export const { handlers, signIn, signOut, auth } = NextAuth({
  providers: [],
})
 // route.ts
import { handlers } from "@/configuration/auth";

export const { GET, POST } = handlers

We can verify the behavior by browsing to the API method. For example, we can test the ‘Signin’ API method directly in the browser.

http://localhost:3000/api/auth/signin

Auth.js Signin method (no providers listing).

Step 3 source

Yes, No providers listing. We’ll list them up in a minute.

4. Setup required providers.

Yes, it’s easy—just import the required providers and configure them. Always remember to set up your app with your provider and add the CLIENT_ID and CLIENT_SECRET values in the .env file.

If you want to get started quickly, here’s how to set it up with GitHub. https://authjs.dev/guides/configuring-github

The OAuth providers supported by Auth.js are listed here.

 //auth.ts
import NextAuth from "next-auth"
import Github from "next-auth/providers/github"
import Google from "next-auth/providers/google"
import Facebook from "next-auth/providers/facebook"
 
export const { handlers, signIn, signOut, auth } = NextAuth({
  providers: [Github, Google, Facebook],
})

Auth.js Signin method with few providers.

Step 4 source

5. Session Management.

You can use session.user to validate if there is a valid user after logging in with an OAuth provider.

// user-avator.tsx
import { auth } from "@/configuration/auth"
export default async function UserAvatar() {
    const session = await auth()

    if (!session?.user) return null

    return (
        <div>
            {
                session.user.image && (
                    <img src={session.user.image} className="avator-image" alt="User Avatar" />
                )
            }
            <h5><a href="/pages/profile">{session.user.name}</a></h5>
        </div>
    )
}

Sign-in helper component.

// Sign-in.tsx 
import { signIn } from "@/configuration/auth"

export default function SignIn() {
  return (
    <form
      action={async () => {
        "use server"
        await signIn()
      }}
    >
      <button className="btn btn-blue" type="submit">Signin</button>
    </form>
  )
} 

Auth.js user avator with session and sign-in.

Step 5 source

New Sign out component in pages\profile\page.tsx Step 5 source with sign out

6. Middleware base Route protection

All protected content routes are secured using a middleware-based route guard (middleware.ts). Protected pages are configured within the same file. In the following middleware, users are redirected to the /pages/login route if they try to access a protected route without a valid user session.

//middleware.ts
import { auth } from "./configuration/auth"

//routes should protected
export const config = {
  matcher: ['/pages/profile', '/pages/protectedPage1'],
}

export default auth((req) => {
  if (!req.auth) {
    const newUrl = new URL("/pages/login", req.nextUrl.origin)
    return Response.redirect(newUrl)
  }
})

Step 6 source

Check complete github repo

I hope this helps, and I look forward to seeing you build your next tool with OAuth. Thank you!