Nest Authbeta

Apple OAuth

Sign in with Apple.

Required by Apple's App Store guidelines if you offer any other social sign-in. The configuration is more involved than Google or Facebook because Apple uses a private-key-signed JWT for client authentication.

Server config

NestAuthModule.forRoot({
  apple: {
    clientId: process.env.APPLE_CLIENT_ID,         // Service ID
    teamId: process.env.APPLE_TEAM_ID,
    keyId: process.env.APPLE_KEY_ID,
    privateKey: process.env.APPLE_PRIVATE_KEY,     // PEM-encoded p8
    redirectUri: process.env.APPLE_REDIRECT_URI,
  },
});

Add the optional peer dep:

pnpm add apple-auth

Generating credentials

  1. In Apple Developer, create a Service ID — this is your clientId.
  2. Enable "Sign In with Apple" on it. Add your redirect URI.
  3. Create a Key, enabling "Sign In with Apple". Download the .p8 file. The Key ID is keyId; the Team ID is teamId.
  4. Convert the .p8 to a single-line env var (replace newlines with \n).

Endpoint

MethodPathBody
POST/auth/login{ providerName: 'apple', credentials: { token, firstName?, lastName? } }

token is the Apple identityToken returned by their JS SDK or native frameworks.

Capturing the user's name (first sign-in only)

Apple returns the user's name only on the very first authorization, and only to your app (in the authorization user object) — it is never in the identityToken, so it is gone on every later login. Capture it on that first sign-in and forward it, and the backend persists it (into the user's metadata, and to your user.beforeCreate/afterCreate hooks as firstName/lastName):

Credential fieldNotes
firstName / lastNameThe given/family name from Apple's first-login user.name. Preferred over name.
nameA combined full name — accepted as a fallback if you only have one string.
avatarUrlApple provides no profile photo. Only send one if your app has it from elsewhere.

Heads up. If you don't capture the name on the first sign-in, you cannot get it later from Apple. To re-request it, remove the app from the user's Apple ID settings (Settings → Apple ID → Sign in with Apple).

Client call (web)

Apple's JS SDK returns the name under response.user on the first sign-in:

import AppleSignin from 'react-apple-signin-auth';
import { useNestAuth } from '@ackplus/nest-auth-react';
 
function AppleSignIn() {
  const { login } = useNestAuth();
 
  return (
    <AppleSignin
      authOptions={{
        clientId: 'com.example.web',
        scope: 'email name',
        redirectURI: window.location.origin + '/auth/apple/callback',
        usePopup: true,
      }}
      onSuccess={(response) =>
        login({
          providerName: 'apple',
          credentials: {
            token: response.authorization.id_token,
            // Present only on the FIRST sign-in — forward it so it isn't lost.
            firstName: response.user?.name?.firstName,
            lastName: response.user?.name?.lastName,
          },
        })
      }
    />
  );
}

Email-relay quirk

Apple lets users hide their real email behind a relay address (abc123@privaterelay.appleid.com). The library stores whatever Apple returns. If you need the real email, you have to ask the user separately — Apple won't give it to the library.

On this page