用于Apple AppStoreConenct API Auth的PHP的ES256 JWT登录 [英] ES256 JWT Signing in PHP for Apple AppStoreConenct API Auth
问题描述
我正在尝试使用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屋!