据我了解,我有两种向Apple APN发送推送通知的方法:基于证书和基于令牌。我选择了基于令牌的
Apple指南说,我们需要创建一个令牌并至少每小时刷新一次。因此,我创建了一个cron作业,该作业每小时刷新一次此令牌,并将其放入服务器上的文件中。另一个cron作业读取此令牌,以每秒发送新的未决推送通知。
问题出在我每小时启动的refresh_token作业中。我使用此库来创建JWT:https://web-token.spomky-labs.com/v/v2.x/components/signed-tokens-jws/jws-creation
这是我的代码(我只是按照刚刚给出的链接指南进行操作):
$algorithmManager = AlgorithmManager::create([
new ES256()
]);
// Our key.
$jwk = new JWK([
'kty' => 'EC', // *** PROBLEM HERE ***
'k' => $keyFile
]);
// The JSON Converter.
$jsonConverter = new StandardConverter();
// We instantiate our JWS Builder.
$jwsBuilder = new JWSBuilder(
$jsonConverter,
$algorithmManager
);
// The payload we want to sign. The payload MUST be a string hence we use our JSON Converter.
$payload = $jsonConverter->encode([
'iat' => time(),
'nbf' => time(),
'exp' => time() + 3600,
'iss' => APPLE_TEAM_ID
]);
$jws = $jwsBuilder
->create()
->withPayload($payload)
->addSignature($jwk, /* with header: */['kid' => APPLE_KEY_NAME, 'alg' => 'ES256'])
->build();
此代码在-> build()处引发异常;功能,最后。它表示未在密钥中指定x,y和crv参数。这些参数似乎与算法(ES256)有关,因为当我选择JWT指南中提供的算法时,它们不会向我询问这些参数。
尽管如此,苹果公司并没有在网站上提供任何有关他们给我的钥匙的信息。这是他们的指南:https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_token-based_connection_to_apns
答案 0 :(得分:1)
加载密钥的方式不正确。本指南中的密钥对应于八位位组密钥,而不是EC密钥。 JWK EC密钥应看起来像the example showed in the RFC7517 section 3(带有crv
,x
和y
参数)。
您必须将从Apple服务收到的密钥文件转换为JWK EC密钥。 由于您已经在平台上安装了PHP,因此建议您使用CLI tool:
curl -OL https://github.com/web-token/jwt-app/raw/gh-pages/jose.phar
curl -OL https://github.com/web-token/jwt-app/raw/gh-pages/jose.phar.pubkey
chmod +x jose.phar
# Replace `/path/to/you/private/key/file.p8` with the actual path to your private key
./jose.phar key:load:key /path/to/you/private/key/file.p8
rm ./jose.phar
rm ./jose.phar.pubkey
您应该得到类似{"kty":"EC","crv":"P-256","d":"…","x":"…","y":"…"}
的东西。
可以使用以下代码行加载JWK:
$jwk = JWK::createFromJson('{"kty":"EC","crv":"P-256","d":"…","x":"…","y":"…"}');