DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Your API Authentication Isn’t Broken; It’s Quietly Failing in These 6 Ways
  • Designing Secure APIs: A Developer’s Guide to Authentication, Rate Limiting, and Data Validation
  • API and Security: From IT to Cyber
  • When APIs Go Wrong: Neglecting Rate Limiting

Trending

  • Rethinking Java CRUDs With Event Sourcing and CQRS Patterns
  • Run Gemma 4 on Your Laptop: A Hands-On Guide to Google's Latest Open Multimodal LLM
  • A Hands-On ABAP RESTful Programming Model Guide
  • What Is Plagiarism? How to Avoid It and Cite Sources
  1. DZone
  2. Data Engineering
  3. Data
  4. How To Implement OAuth User Authentication in Next.js

How To Implement OAuth User Authentication in Next.js

Learn how to authenticate your users in your Next.js app (app router) with providers like Google, GitHub, Twitter, Spotify, and more.

By 
Krste Rajchevski user avatar
Krste Rajchevski
·
Nov. 08, 23 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
6.8K Views

Join the DZone community and get the full member experience.

Join For Free

In this article, we will learn how to add user authentication with OAuth providers in your Next.js app. To do so, we’ll be using NextAuth.js, which is a user authentication solution that simplifies the whole process and has built-in support for many popular sign-in services.

What’s OAuth?

OAuth (Open Authorization) is an open standard for access delegation, commonly used as a way for Internet users to grant websites or applications access to their information on other websites but without giving them the passwords. 

When you use OAuth authentication with providers (like Google, Facebook, Twitter, etc.), you are using a protocol that allows you to authorize applications to use your personal information from the provider without needing to expose your password. This is achieved by sharing tokens instead of credentials, which can be restricted for use with specific resources or services.

The main advantage is that you don't have to deal with different authentication methods offered by various web services. OAuth is widely accepted and used by many popular applications on the internet.

Setup NextAuth.js

1. Install NextAuth.js

JavaScript
 
npm install next-auth


2. Add NEXTAUTH_SECRET to Your .env.local File

After successful sign in, NextAuth.js generates a cookie with a JWT token used for user identification and it's encrypted using the NEXTAUTH_SECRET value.


You can generate a random value using openssl rand -base64 32 or generate-secret.vercel.app and add it to your .env.local file.


3. Add Route Handler to Your Next.js App

To add NextAuth.js to your project, you will need to create a dynamic Route Handler.  To do so, create a file called route.js|ts in app/api/auth/[…nextauth]. This file will also contain all of your global NextAuth.js configurations.

Route Handlers are the equivalent of API Routes inside the pages directory, meaning you do not need to use API Routes and Route Handlers together. If you're using an older version of Next.js with the pages Route, here’s an example of how to initialize an API route.

In my route.ts file below, I managed to set up authentication with four different providers: Google, LinkedIn, GitHub, and Spotify.

JavaScript
 
import NextAuth, { NextAuthOptions } from "next-auth";
import GoogleProvider from "next-auth/providers/google";
import LinkedInProvider from "next-auth/providers/linkedin";
import GitHubProvider from "next-auth/providers/github";
import SpotifyProvider from "next-auth/providers/spotify";

export const authOptions: NextAuthOptions = {
  providers: [
    GoogleProvider({
      clientId: String(process.env.GOOGLE_CLIENT_ID),
      clientSecret: String(process.env.GOOGLE_CLIENT_SECRET),
    }),
    GitHubProvider({
      clientId: String(process.env.GITHUB_CLIENT_ID),
      clientSecret: String(process.env.GITHUB_CLIENT_SECRET),
    }),
    // LinkedIn recently changed their OAuth flow which is why there is a bit extra code
    LinkedInProvider({
      clientId: String(process.env.LINKEDIN_CLIENT_ID),
      clientSecret: String(process.env.LINKEDIN_CLIENT_SECRET),
      authorization: {
        params: { scope: "openid profile email" },
      },
      issuer: "https://www.linkedin.com",
      jwks_endpoint: "https://www.linkedin.com/oauth/openid/jwks",
      profile(profile, tokens) {
        const defaultImage =
          "https://cdn-icons-png.flaticon.com/512/174/174857.png";
        return {
          id: profile.sub,
          name: profile.name,
          email: profile.email,
          image: profile.picture ?? defaultImage,
        };
      },
    }),
    SpotifyProvider({
      clientId: String(process.env.SPOTIFY_CLIENT_ID),
      clientSecret: String(process.env.SPOTIFY_CLIENT_SECRET),
    }),
  ],
};

const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };


What Did We Achieve With the Route Handler?

Thanks to our Route Handler, now all requests to /api/auth/* like signIn, callback, signOut, etc.) will automatically be handled by NextAuth.js. Out of the box, we get a simple Sign-in page (/API/auth/signin). After a successful sign-in, you will notice a JWT token in your cookies. The same JWT token is signed with your NEXT_SECRET that we created in the previous step.

How Do I get the clientId and clientSecret? 

Usually, the process involves creating an OAuth app on your desired service (i.e., Google) and generating a key and secret that you need to add to your .env.local file. 

Step-by-Step Implementation

Imagine we want to implement authentication with X (ex Twitter). Here are all the steps we need to take to do so.

  1. For authentication with X (ex Twitter), simply follow NextAuth.js’s guide to get the clientId and clientSecret at next-auth.js. Remember to carefully read the documentation for the provider you want to use.
  2. Here’s a short video on how to get Twitter's clientId and clientSecret:
    Note: The process may vary for different services. Refer to the provider's documentation (see Step 1). 

    For Twitter:
    • Use the OAuth 2.0 version.
    • Select 'Native App'.
    • Set the Redirect URL to /api/auth/callback/twitter. Use 'localhost:3000' for development. You can add your production Callback URI/Redirect URL later.
  3. Copy-paste the clientId and clientSecret in your .env.local file.
  4. Import the Twitter provider and initialize it in the list of providers in your route.ts
  5. JavaScript
     
    // ...code
    import TwitterProvider from "next-auth/providers/twitter";
    
    export const authOptions: NextAuthOptions = {
      // ...code
      providers: [
        // ...other providers
        TwitterProvider({
          clientId: process.env.TWITTER_CLIENT_ID,
          clientSecret: process.env.TWITTER_CLIENT_SECRET,
          version: "2.0", // opt-in to Twitter OAuth 2.0
        }),
      ],
    };
    // ...code


  6. That’s it! Go to your /api/auth/signin, and you will see your new provider.

Sign-in page with all the implemented providers.

Sign-in page with all the implemented providers.


Most Common Issues I Faced

Even though the process from a coding perspective is straightforward and simple, I encountered a few challenges because each service has a unique way of creating an OAuth app and generating the clientId and clientSecret.

Also, make sure you set up the Redirect URI/Callback URL correctly for each service. It looks like this /api/auth/callback/<name_of_provider>. For example, for GitHub, it’s locahost:3000.

Make sure you set the correct Redirect URI/Callback URL in production.
You can use localhost:3000 while in development.

The last thing is to make sure you set up the correct scope and permissions. Basically, you will need to set which information your OAuth app will ask users for, such as email, name, and profile_photo.

In case things get weird while developing, clear the cookies and try again.

Example

I’ve created a small Next.js (v14) app that you can play with and see how I implemented authentication with all these providers. Bonus: I also managed to create a protected route with content that will be shown only to authenticated users.

App: next-auth-providers-example
GitHub: next-auth-providers-example

Summary

  • Install NextAuth.js (npm install next-auth). You need to add NEXTAUTH_SECRET in your .env.local file in order for NextAuth.js to work.
  • Add a Route Handler for NextAuth.js (or API Route for older Next.js versions). You can copy-paste the example provided above.
  • Create an OAuth app for the provider that you want to implement, get the clientId and clientSecret, and add them to your .env.local file.
  • Inside your RouteHandler (route.ts file), import the provider and add them to the array of providers, bypassing the clientId and clientSecret from your .env.local file.
API Next.js authentication security Data Types

Opinions expressed by DZone contributors are their own.

Related

  • Your API Authentication Isn’t Broken; It’s Quietly Failing in These 6 Ways
  • Designing Secure APIs: A Developer’s Guide to Authentication, Rate Limiting, and Data Validation
  • API and Security: From IT to Cyber
  • When APIs Go Wrong: Neglecting Rate Limiting

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook