← Back to Blog

How to implement Sign in with Apple using NextAuth in NextJs

Jordan Mungujakisa
6 min read

Why This Matters

I always thought adding Sign in with Apple would be complicated, typical of all other Apple services. But I recently implemented Apple Auth in a NextJS app using NextAuth, and it was easier than I had expected.

Here are the exact steps I followed to implement this in less than an hour.

Sign in with Apple

TL;DR

  1. Create an App ID (enable Sign in with Apple)
  2. Create a Service ID (the identifier becomes your Client ID)
  3. Create a Key and download the .p8 file
  4. Configure environment variables using npx auth add apple
  5. Add the Apple provider in NextAuth
  6. Implement your callback logic
  7. Add a “Sign in with Apple” button

Step 1: Create an App ID

Go to the Apple Developer Identifiers page and create an App ID. Enable Sign in with Apple, then save and continue.

Follow Apple’s official instructions to create an App ID — remember to select "Sign in with Apple".

Note: Apple requires an App ID with Sign in with Apple enabled, plus a separate Service ID for web authentication. These must be explicitly differentiated.


Step 2: Create a Service ID (Client ID)

Visit the Service IDs page and create a new Service ID.

Important: Note down the identifier of the Service ID — this will be your Client ID.

When creating the Service ID, enable Sign in with Apple and configure:

  • Primary App ID: Select the App ID you created in Step 1
  • Domain: Your domain (e.g., example.com)
  • Return URL: Your OAuth callback URL (e.g., https://example.com/api/auth/callback/apple)

Tip: The callback URL must be HTTPS. For local testing, use a tunneling service like ngrok to expose your app.

Reference: Register a Services ID


Step 3: Create a Key and Download the .p8 File

Visit the Auth Keys page and create a new key. Link it to your App and enable Sign in with Apple.

  • Save the Key ID — you’ll need it later
  • Download the .p8 private key file (this can only be downloaded once!)

Reference: Create a private key


Step 4: Note Your Team ID

Find your Team ID in the top-right corner of your Apple Developer account dashboard. You’ll need it to generate the client secret.


Step 5: Install NextAuth

Install the next-auth package in your project:

npm install next-auth

# or using yarn
yarn add next-auth

Step 6: Configure Environment Variables

After installing next-auth, generate your AUTH_APPLE_ID and AUTH_APPLE_SECRET environment variables by running:

npx auth add apple

You’ll be prompted to provide:

Client ID:        # Your Service ID identifier from Step 2
Key ID:           # From Step 3
Team ID:          # From Step 4
Path to Private Key:  # Path to your .p8 file

Step 7: Configure the Apple Provider

Create or update your NextAuth route at app/api/auth/[...nextauth]/route.ts:

import NextAuth from "next-auth";
import Apple from "next-auth/providers/apple";

export const authOptions = {
  providers: [
    Apple({
      clientSecret: {
        teamId: process.env.AUTH_APPLE_ID!,
        privateKey: process.env.AUTH_APPLE_SECRET!,
      },
    }),
  ],

  callbacks: {
    async signIn({ user, account, profile }) {
      // Optional: add custom logic to validate users
      return true;
    },

    async session({ session, token }) {
      // Optional: enrich session with additional data
      return session;
    },
  },
};

export default NextAuth(authOptions);

Note: By default, NextAuth uses /api/auth/callback/apple. Ensure this exact HTTPS URL is set in your Apple Service ID settings.


Step 8: Add a Sign-In Button

Add a sign-in button to your UI:

"use client";

import { signIn } from "next-auth/react";

export function SignInWithAppleButton() {
  return <button onClick={() => signIn("apple")}>Sign in with Apple</button>;
}

Reference: Sign in with Apple - Get Started


Troubleshooting Tips

IssueSolution
Authentication rejectedApple rejects non-HTTPS or localhost origins. Use a deployed domain or ngrok for testing.
JWT or “invalid_client” errorsDouble-check your Team ID, Key ID, Client ID, and callback URL.
Security concernsKeep your .p8 file secure and never commit it to version control. Rotate keys if compromised.

If you try this flow, let me know in the comments. And if you found this helpful, consider sharing it with a teammate!

0 Comments

No comments yet. Be the first to share your thoughts!