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.
TL;DR
- Create an App ID (enable Sign in with Apple)
- Create a Service ID (the identifier becomes your Client ID)
- Create a Key and download the
.p8file - Configure environment variables using
npx auth add apple - Add the Apple provider in NextAuth
- Implement your callback logic
- 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
.p8private 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
| Issue | Solution |
|---|---|
| Authentication rejected | Apple rejects non-HTTPS or localhost origins. Use a deployed domain or ngrok for testing. |
| JWT or “invalid_client” errors | Double-check your Team ID, Key ID, Client ID, and callback URL. |
| Security concerns | Keep 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!