ES256 JWT Вход в PHP для Apple AppStoreConenct API Auth - PullRequest
0 голосов
/ 16 июня 2019

Я пытаюсь пройти аутентификацию в Apple AppStoreConnect API с подписанным ES256 JWT (согласно их инструкциям на https://developer.apple.com/documentation/appstoreconnectapi) с использованием PHP.

Отправка моего запроса всегда приводит к ошибке 401 NOT_AUTHORIZED.

Я убедился, что содержимое моего заголовка и утверждений правильное - я даже нашел в Интернете скрипт Ruby для генерации JWT с подписью ES256 и использования предоставленного Apple эмитента, идентификатора ключа, секретного ключа, он работаетплавно - Apple принимает токен, который говорит мне, что мои учетные данные хороши, и я делаю что-то не так в php.

Если я просто не слишком долго смотрю на этот код, формат JWT правильный,Base64 закодирован правильно, и токен носителя установлен правильно в заголовке.

Чтобы исключить проблему с отправкой запроса, я попробовал и GuzzleHTTP, и CLI cURL - оба 401.


Вот соответствующий код. Вы увидите, что метод create кодирует заголовок и утверждения, подписывает «полезную нагрузку» и объединяет все 3.

public function create()
{
    $header = $this->encode(
        json_encode([
            'kid' => 'my_key_id',
            'alg' => 'ES256',
            'typ' => 'JWT',
        ])
    );

    $claims = $this->encode(
        json_encode([
            'iss' => 'my_issuer_uuid',
            'exp' => time() + (20 * 60),
            'aud' => 'appstoreconnect-v1',
        ])
    );

    $signature = $this->encode(
        $this->sign("$header.$claims")
    );

    return $header . '.' . $claims . '.' . $signature;
}

Этот код успешно возвращает открытый ресурс ssl, $data содержит ожидаемое содержимое.

public function sign($data)
{
    if (!$key = openssl_pkey_get_private('file://my_key_file.p8')) {
        throw new \Exception('Failed to read PEM');
    }

    if (!openssl_sign($data, $signature, $key, OPENSSL_ALGO_SHA256)) {
        throw new \Exception('Claims signing failed');
    }

    return $signature;
}

Base64 URL-кодировка ... $data содержит ожидаемое содержимое.

public function encode($data)
{
    return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($data));
}

На данный момент я в тупике, что я делаю неправильно или отсутствует.Я надеюсь, что некоторые дополнительные глаза найдут что-нибудь!Используя токен, который выводит мой код:

curl  https://api.appstoreconnect.apple.com/v1/users --Header "Authorization: Bearer <token>”

... всегда возвращает 401.Я подозреваю, что что-то не так в части кода для подписи, поскольку это единственная часть, которую я не смог проверить (опять же, работал в Ruby), хотя, глядя на все документы и примеры для openssl_sign, я довольноконечно, это правильно.

Для справки, это упомянутый мной скрипт Ruby https://shashikantjagtap.net/generating-jwt-tokens-for-app-store-connect-api/

1 Ответ

0 голосов
/ 17 июня 2019

Подпись, возвращаемая OpenSSL, представляет собой последовательность ASN.1, которая содержит дополнительную информацию. Вы должны удалить дополнительные данные перед объединением.

Вы можете использовать этот простой класс, который я написал (метод fromDER) для преобразования подписи OpenSSL.

...