웹에서 Sign in with Apple을 사용하기 위한 Apple Developer 설정을 정리합니다. Primary App ID와 Services ID 연결, 도메인과 Return URL 등록, .p8 private key 발급까지 화면과 함께 진행합니다.
웹에서 Apple로 로그인을 구현하려면 코드를 작성하기 전에 Apple Developer 설정을 먼저 마쳐야 합니다.
이 설정은 React, Next.js, 어떤 백엔드를 사용하든 동일합니다. 프레임워크마다 반복해서 설명할 필요가 없기 때문에 이 글로 분리했습니다.
이 글에서는 다음 과정을 순서대로 진행합니다.
.p8 private key 다운로드설정을 마치면 프레임워크 구현 글로 이어집니다.
처음 설정할 때 가장 헷갈리는 부분은 App ID와 Services ID를 왜 둘 다 만들어야 하는가입니다.
Apple은 하나의 서비스를 App ID로 식별합니다. 그런데 웹에는 앱처럼 설치되는 실체가 없기 때문에, 웹사이트를 가리키는 별도의 식별자인 Services ID를 만들고 이것을 App ID에 연결하는 구조를 사용합니다.
Primary App ID (com.recodelog.myservice)
│ Sign in with Apple 활성화, Enable as a primary App ID
│
├─ Services ID (com.recodelog.myservice.web)
│ 웹의 client_id로 사용
│ 도메인과 Return URL을 등록
│
└─ Key (.p8)
서버에서 client_secret JWT를 서명할 때 사용즉 웹에서 실제로 client_id로 사용하는 값은 Services ID이고, App ID는 그 기준이 되는 상위 식별자입니다. 앱과 웹에서 같은 Apple 계정을 같은 사용자로 인식하려면 두 식별자가 반드시 연결되어 있어야 합니다.
설정을 시작하기 전에 다음 항목이 필요합니다.
이 글에서는 다음 값을 예시로 사용합니다.
Primary App ID: com.recodelog.myservice
Services ID: com.recodelog.myservice.web
Domain: recodelog.com
Return URL: https://recodelog.com/auth/apple/callback예시 값은 자신의 프로젝트에 맞게 변경해야 합니다.
웹에서 Apple 로그인을 사용할 때도 먼저 Sign in with Apple이 활성화된 Primary App ID가 필요합니다.
웹에서 실제 client_id로 사용하는 값은 이후 생성할 Services ID지만, Services ID를 단독으로 사용할 수는 없습니다. 기준이 되는 App ID를 생성한 후 두 식별자를 연결해야 합니다.
Apple Developer의 Certificates, Identifiers & Profiles로 이동합니다.
Identifiers 메뉴로 이동한 후 제목 옆의 + 버튼을 클릭합니다.

Apple Developer Identifiers 목록과 추가 버튼
새 Identifier의 종류로 App IDs를 선택하고 Continue를 클릭합니다.

새 Identifier에서 App IDs 선택
App ID 타입은 App을 선택합니다.

App ID 타입에서 App 선택
Description과 Bundle ID를 입력합니다. Bundle ID는 Explicit을 선택하고 프로젝트를 구분할 수 있는 고유한 값을 사용합니다.

App ID Description과 Bundle ID 입력
com.recodelog.myserviceCapabilities 목록에서 Sign in with Apple을 찾아 체크합니다.

App ID의 Sign in with Apple capability 활성화
Edit 또는 Configure를 클릭한 후 Enable as a primary App ID를 선택합니다.

Sign in with Apple에서 Primary App ID 설정
설정을 저장하고 App ID 등록을 완료합니다.
다음은 웹사이트를 식별하는 Services ID를 생성합니다.
웹에서는 Services ID가 Apple 인증 요청의 client_id로 사용됩니다.
다시 Identifiers 화면의 + 버튼을 클릭하고 이번에는 Services IDs를 선택합니다.

새 Identifier에서 Services IDs 선택
Description과 Identifier를 입력합니다.

웹용 Services ID의 Description과 Identifier 입력
이 글에서는 다음 값을 사용합니다.
Description: Recodelog Web
Identifier: com.recodelog.myservice.webServices ID의 Identifier는 이후 프론트엔드와 백엔드에서 모두 client_id로 사용하므로 정확하게 보관합니다.
등록을 마치면 Identifiers 화면의 필터에서 Services IDs를 선택합니다.

Identifiers 목록에서 Services IDs 필터 선택
목록에서 방금 생성한 Services ID를 확인할 수 있습니다.

등록을 마친 Services ID 목록
Services ID를 생성한 뒤 목록에서 방금 만든 Services ID를 다시 선택합니다.
Sign in with Apple을 체크합니다.Configure를 클릭합니다.
Services ID에서 Sign in with Apple 활성화
Configure를 클릭하면 Web Authentication Configuration 화면이 열립니다. Primary App ID를 선택하고 웹 도메인과 Return URL을 입력합니다.

Services ID에 웹 도메인과 Return URL 등록
Domains and Subdomains에는 프로토콜과 경로를 제외한 호스트명만 입력합니다.
recodelog.comReturn URLs에는 Apple 인증 완료 후 결과를 받을 전체 HTTPS URL을 입력합니다.
https://recodelog.com/auth/apple/callbackReturn URL은 여러 개를 등록할 수 있습니다. 스테이징과 프로덕션 도메인을 함께 사용한다면 이 단계에서 모두 등록해 두는 것이 편합니다.
https://recodelog.com/auth/apple/callback
https://staging.recodelog.com/auth/apple/callback설정을 저장하면 웹에서 사용할 Services ID 준비가 완료됩니다.
백엔드가 Apple의 Token Endpoint와 통신하려면 client_secret이 필요합니다.
Apple의 client_secret은 일반적인 고정 문자열이 아닙니다. Apple Developer에서 발급한 .p8 private key를 사용하여 백엔드에서 JWT 형태로 생성합니다.
Apple Developer의 Keys 메뉴로 이동합니다.

Apple Developer의 Keys 목록과 추가 버튼
제목 옆의 + 버튼을 클릭합니다. Key Name을 입력하고 Sign in with Apple을 체크합니다.

Key Name 입력 후 Sign in with Apple 활성화
Configure를 클릭한 후 앞에서 생성한 Primary App ID를 선택합니다.

Sign in with Apple Key에 Primary App ID 연결
설정을 저장한 뒤 등록 내용을 확인하고 Register를 클릭합니다.

Sign in with Apple Key 등록 내용 확인
Key 등록을 완료하면 .p8 파일을 다운로드할 수 있습니다.

Sign in with Apple private key 다운로드
여기까지 진행하면 구현에 필요한 값이 모두 준비됩니다.
| 값 | 어디서 확인하는가 | 사용하는 곳 | 브라우저 노출 |
|---|---|---|---|
| Team ID | Apple Developer 우측 상단 또는 Membership | 서버 (client_secret의 iss) | 서버 전용 |
| Key ID | Keys 메뉴의 Key 상세 화면 | 서버 (client_secret의 kid) | 서버 전용 |
.p8 private key | Key 등록 후 다운로드한 파일 | 서버 (client_secret 서명) | 서버 전용 |
| Services ID | Identifiers의 Services IDs 목록 | 프론트엔드와 서버의 client_id | 노출 가능 |
| Return URL | Services ID의 Web Authentication 설정 | 프론트엔드와 서버의 redirect_uri | 노출 가능 |
Services ID와 Return URL은 인증 요청 URL에 그대로 들어가는 값이라 브라우저에 노출되어도 문제가 없습니다. 반면 Team ID, Key ID, .p8 private key는 이 세 가지가 모이면 우리 서비스를 사칭하는 client_secret을 만들 수 있으므로 반드시 서버에만 둡니다.
APPLE_TEAM_ID=TODO_APPLE_TEAM_ID
APPLE_KEY_ID=TODO_APPLE_KEY_ID
APPLE_CLIENT_ID=com.recodelog.myservice.web
APPLE_REDIRECT_URI=https://recodelog.com/auth/apple/callback
APPLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"설정 단계에서 가장 많이 만나는 오류입니다. 다음 값이 서로 다를 때 발생합니다.
client_id와 실제 Services IDclient_secret의 sub와 Services IDclient_secret의 iss와 Team IDclient_secret 서명에 사용한 Key와 kid에 넣은 Key IDredirect_uri특히 App ID를 client_id로 잘못 넣는 경우가 많습니다. 웹에서는 Services ID를 사용합니다.
Services ID의 Web Authentication 설정에 현재 접속한 도메인이 등록되어 있지 않을 때 발생합니다. Domains and Subdomains에 호스트명이 정확히 들어가 있는지 확인합니다.
Apple Developer의 도메인과 Return URL 변경은 반영까지 시간이 걸릴 수 있습니다. 설정을 저장한 직후 실패한다면 몇 분 뒤에 다시 시도해 봅니다.
Apple은 웹 Return URL로 localhost와 http를 허용하지 않습니다. 로컬 개발 중이라면 다음 방법 중 하나를 사용합니다.
이 글에서는 Apple 로그인 구현에 필요한 Apple Developer 설정을 정리했습니다.
.p8 private key 발급과 값 보관설정은 프레임워크와 무관하게 동일하므로, 이제 사용하는 스택에 맞는 구현 글로 이어서 진행하면 됩니다.