【发布时间】:2019-08-22 11:27:00
【问题描述】:
我需要使用 .p8 文件通过 PHP 脚本发送推送通知,并在 here 提出的类似问题中找到以下代码。
<?php
$keyfile = 'AuthKey_AABBCC1234.p8'; # <- Your AuthKey file
$keyid = 'AABBCC1234'; # <- Your Key ID
$teamid = 'AB12CD34EF'; # <- Your Team ID (see Developer Portal)
$bundleid = 'com.company.YourApp'; # <- Your Bundle ID
$url = 'https://api.development.push.apple.com'; # <- development url, or use http://api.push.apple.com for production environment
$token = 'e2c48ed32ef9b018........'; # <- Device Token
$message = '{"aps":{"alert":"Hi there!","sound":"default"}}';
$key = openssl_pkey_get_private('file://'.$keyfile);
$header = ['alg'=>'ES256','kid'=>$keyid];
$claims = ['iss'=>$teamid,'iat'=>time()];
$header_encoded = base64($header);
$claims_encoded = base64($claims);
$signature = '';
openssl_sign($header_encoded . '.' . $claims_encoded, $signature, $key, 'sha256');
$jwt = $header_encoded . '.' . $claims_encoded . '.' . base64_encode($signature);
// only needed for PHP prior to 5.5.24
if (!defined('CURL_HTTP_VERSION_2_0')) {
define('CURL_HTTP_VERSION_2_0', 3);
}
$http2ch = curl_init();
curl_setopt_array($http2ch, array(
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0,
CURLOPT_URL => "$url/3/device/$token",
CURLOPT_PORT => 443,
CURLOPT_HTTPHEADER => array(
"apns-topic: {$bundleid}",
"authorization: bearer $jwt"
),
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $message,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_TIMEOUT => 30,
CURLOPT_HEADER => 1
));
$result = curl_exec($http2ch);
if ($result === FALSE) {
throw new Exception("Curl failed: ".curl_error($http2ch));
}
$status = curl_getinfo($http2ch, CURLINFO_HTTP_CODE);
echo $status;
function base64($data) {
return rtrim(strtr(base64_encode(json_encode($data)), '+/', '-_'), '=');
}
?>
但是,我发现openssl_pkey_get_private 没有读取密钥文件,并且在调试时出现以下错误。
$key = openssl_pkey_get_private('file://'.$keyfile);
if ($key === false) {
var_dump(openssl_error_string());
}
错误:
'error:02001002:system library:fopen:No such file or directory'
请注意curl 没有问题,因为HTTP2 已为curl 启用,而我正在使用PHP7。在测试阶段,我使用同一文件夹中的脚本和文件来避免任何路径问题。
任何线索哪里出错了?
【问题讨论】:
-
$keyfile 的内容是什么?您可以从终端实际打开该文件吗?它似乎不存在,因此抛出“没有这样的文件或目录”错误。
-
是的,我可以打开它。我将 php 脚本和 .p8 文件放在同一个文件夹中,并且在给 file:// 时没有指定任何路径。
-
您使用的是什么操作系统?基于unix的区分大小写。我试过你的代码,它工作正常:它抛出 string(50) "error:0909006C:PEMroutines:get_name:no start line" 而不是找不到文件错误
-
我的错,我没有提到它。我在 Windows 10 上使用 wamp 服务器。
-
我尝试使用浏览器而不是通过终端复制它。如果通过浏览器访问,则需要提供绝对路径。像这样:openssl_pkey_get_private('file:///C:/xampp/htdocs/'.$keyfile);
标签: php openssl apple-push-notifications p8