用于Apple AppStoreConenct API Auth的PHP的ES256 JWT登录 [英] ES256 JWT Signing in PHP for Apple AppStoreConenct API Auth

查看:810
本文介绍了用于Apple AppStoreConenct API Auth的PHP的ES256 JWT登录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用ES256签名的JWT对Apple的AppStoreConnect API进行身份验证(按照 https中的说明进行操作使用PHP的://developer.apple.com/documentation/appstoreconnectapi ).

I'm trying to authenticate to Apple's AppStoreConnect API with an ES256 signed JWT (per their instructions at https://developer.apple.com/documentation/appstoreconnectapi) using PHP.

发送我的请求始终会导致401 NOT_AUTHORIZED错误.

Sending my request always results in a 401 NOT_AUTHORIZED error.

我已经验证了标头和声明的内容是否正确-我什至在网上找到了一个Ruby脚本,用于生成ES256签名的JWT,并使用我的Apple提供的Issuer,Key ID,Private Key,它可以顺畅地工作-Apple接受令牌.这说明我的凭据很好,并且我在php中做错了事.

I've verified that the the contents of my header and claims are correct - I even found a Ruby script online for generating an ES256 signed JWT and using my Apple provided Issuer, Key ID, Private Key, it works swimmingly - Apple accepts the token. That tells me that my credentials are good and I'm doing something wrong in php.

除非我只是盯着这段代码太长时间,否则JWT格式是正确的,base64编码是正确的,并且承载令牌在标头中的设置是正确的.

Unless I've simply stared at this code for too long, the JWT format is correct, base64 encoded correctly, and the bearer token is set correctly in the header.

要排除请求发送方面的问题,我尝试了GuzzleHTTP和CLI cURL-均为401.

To rule out an issue with request sending I've tried both GuzzleHTTP and CLI cURL - both a 401.

这是相关的代码.您会看到create方法正在编码标题和声明,对有效载荷"进行签名,并串联所有3个.

Here's the relevant code. You'll see that the create method is encoding the header and claims, signing the "payload", and concatenating all 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具有预期的内容.

This code successfully returns an open ssl resource, $data has the expected contents.

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具有预期的内容.

Base64 URL encoding... $data has the expected contents.

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

在这一点上,我被弄错了,我做错了什么或想念什么.我希望更多的眼睛能找到一些东西!使用我的代码转储的令牌:

At this point I'm stumped to what it is I'm doing wrong or missing. I'm hoping some extra eyes will find something! Using the token that my code dumps out:

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

...总是返回401.我怀疑代码的签名部分出了问题,因为这是我唯一无法验证的部分(再次在Ruby中工作),尽管查看了openssl_sign的所有文档和示例,我很清楚确定是正确的.

...always returns a 401. I suspect there's something wrong in the signing portion of the code as it's the only part I haven't been able to verify (again, worked in Ruby), though looking at all the docs and examples for openssl_sign, I'm pretty sure it's right.

作为参考,这是我提到的Ruby脚本 https://shashikantjagtap.net/generating-jwt-tokens-for-app-store-connect-api/

For reference, this is the Ruby script I mention https://shashikantjagtap.net/generating-jwt-tokens-for-app-store-connect-api/

推荐答案

在苦苦挣扎之后,我终于使用 https://github.com/lcobucci/jwt

After struggling alot, i finally got it working using https://github.com/lcobucci/jwt

use Curl\Curl;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Ecdsa\Sha256;

$signer = new Sha256();
$privateKey = new Key('file://AuthKey_XYZ.p8');
$time = time();

$Issuer_ID = "FROM_APPLE_PAGE";
$Key_ID = "FROM_APPLE_PAGE";

$token = (new Builder())->issuedBy($Issuer_ID)// Configures the issuer (iss claim)
->permittedFor("appstoreconnect-v1")// Configures the audience (aud claim)
->identifiedBy('XXYYZZ', true)// Configures the id (jti claim), replicating as a header item
->withHeader('kid', $Key_ID)
->withHeader('type', 'JWT')
    ->withHeader('alg', 'ES256')
    ->issuedAt($time)// Configures the time that the token was issue (iat claim)
    ->expiresAt($time + 1200)// Configures the expiration time of the token (exp claim)
    ->withClaim('uid', 1)// Configures a new claim, called "uid"
    ->getToken($signer, $privateKey); // Retrieves the generated token


$token->getHeaders(); // Retrieves the token headers
$token->getClaims(); // Retrieves the token claims

这篇关于用于Apple AppStoreConenct API Auth的PHP的ES256 JWT登录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆