正如我所知,我有两种向Apple APN发送推送通知的方法:基于证书的基于证书和令牌。我选择了基于令牌的
Apple Guide表示,我们至少需要每小时创建一个令牌并刷新它。因此,我创建了一个Cron作业,每小时都会刷新这个令牌,并将其放入服务器上的文件中。另一个Cron Job读了这个令牌,每秒都会发送新的待定推送通知。
我每小时都会启动的Refresh_token工作。我使用此库来创建JWT:https://web-token.spomky-labs.com/v/v/v.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指南中提供的ALG时,它们不会要求我提供这些参数。
不过,苹果没有提供有关他们在网站上给我的密钥的任何信息。这是他们的指南:https://developer.apple.com/documentation/usernotification/setting_up_a_remote_notification_notification_server/establisher/establishing_a_token_a_token astem_connection_connection_to_to_apns
加载键的方式不正确。指南中的钥匙对应于八位位键,而不是ec键。JWK EC密钥应看起来像RFC7517第3节中显示的示例(使用crv
,x
和y
参数(。
您必须将您从Apple Services收到的密钥文件转换为JWK EC密钥。由于您的平台上已经有了PHP,我建议使用CLI工具:
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":"…"}');