Как на PHP реализовать авторизацию пользователей через аккаунт Apple (Sign in with Apple) с использованием JWT?

Sign in with Apple — это механизм OAuth 2.0 / OpenID Connect, который позволяет пользователям входить в приложения через Apple ID. На PHP реализация включает несколько ключевых этапов.

## 1. Регистрация приложения в Apple Developer

Перед написанием кода необходимо:
— Зарегистрировать App ID с поддержкой Sign in with Apple.
— Создать Services ID (это будет ваш `client_id`).
— Сгенерировать ключ (Key) с поддержкой Sign in with Apple — скачать `.p8` файл и запомнить `Key ID` и `Team ID`.
— Указать Redirect URI в настройках Services ID.

## 2. Генерация client_secret (JWT)

Apple требует, чтобы `client_secret` был JWT-токеном, подписанным вашим приватным ключом ES256.

php
use FirebaseJWTJWT;

function generateAppleClientSecret(): string {
$teamId = ‘YOUR_TEAM_ID’;
$clientId = ‘YOUR_SERVICE_ID’;
$keyId = ‘YOUR_KEY_ID’;
$privateKey = file_get_contents(‘/path/to/AuthKey_XXXXXXXX.p8’);

$now = time();
$payload = [
‘iss’ => $teamId,
‘iat’ => $now,
‘exp’ => $now + 86400 * 180, // максимум 6 месяцев
‘aud’ => ‘https://appleid.apple.com’,
‘sub’ => $clientId,
];

return JWT::encode($payload, $privateKey, ‘ES256’, $keyId);
}

Для работы используйте библиотеку `firebase/php-jwt` (устанавливается через Composer).

## 3. Редирект пользователя на Apple

php
$params = http_build_query([
‘client_id’ => ‘YOUR_SERVICE_ID’,
‘redirect_uri’ => ‘https://yourdomain.com/apple/callback’,
‘response_type’ => ‘code id_token’,
‘scope’ => ‘name email’,
‘response_mode’ => ‘form_post’,
‘state’ => bin2hex(random_bytes(16)),
]);
header(‘Location: https://appleid.apple.com/auth/authorize?’ . $params);

## 4. Обработка callback и обмен кода на токены

php
$code = $_POST[‘code’];
$clientSecret = generateAppleClientSecret();

$response = file_get_contents(‘https://appleid.apple.com/auth/token’, false,
stream_context_create([‘http’ => [
‘method’ => ‘POST’,
‘header’ => ‘Content-Type: application/x-www-form-urlencoded’,
‘content’ => http_build_query([
‘client_id’ => ‘YOUR_SERVICE_ID’,
‘client_secret’ => $clientSecret,
‘code’ => $code,
‘grant_type’ => ‘authorization_code’,
‘redirect_uri’ => ‘https://yourdomain.com/apple/callback’,
]),
]])
);
$tokens = json_decode($response, true);

## 5. Верификация id_token

Полученный `id_token` — это JWT. Его необходимо проверить с помощью публичных ключей Apple:

php
$appleKeys = json_decode(file_get_contents(‘https://appleid.apple.com/auth/keys’), true);
// Выбрать нужный ключ по kid из заголовка JWT
// Декодировать и проверить подпись через firebase/php-jwt
$decoded = JWT::decode($tokens[‘id_token’], JWK::parseKeySet($appleKeys));
$userId = $decoded->sub; // уникальный идентификатор пользователя
$email = $decoded->email; // email (только при первом входе)

## 6. Сохранение пользователя

После верификации `sub` используется как уникальный идентификатор. Email и имя приходят только при первом входе, поэтому их нужно сохранить сразу.

## Важные нюансы
— Всегда проверяйте `state` для защиты от CSRF.
— `client_secret` JWT действует максимум 6 месяцев — обновляйте его заранее.
— Apple передаёт имя пользователя только при первом входе через POST-параметр `user`.
— Используйте HTTPS для Redirect URI.


Задайте вопрос нейросети

Не нашли ответ? Спросите ИИ — он подготовит развёрнутую статью.