3

我已经制作了网络服务来使用 curl 向 ios 发送推送通知,我有用于开发的 ck.pem 文件,其中包含证书和 RSA 私钥,并正确引用它。

但每次我调用网络服务时,我都会收到相同的错误 Curl failed: unable to use client certificate (no key found or wrong pass phrase?)

所有相关的解决方案都不起作用,除了使用“stream_context_create”的替代方案,但我想用 curl 和 idk 来做,问题出在哪里。

在我的代码下面找到:

function test_push_to_ios() {
    $url = 'https://gateway.sandbox.push.apple.com:2195';
    $cert = base_url() . 'backend_includes/ios_cert/ck.pem';

    $gcm_ids = array("xxxxxx");
    $passphrase = "passphrase";
    $message = 'nbad_notification';
    $aps = array('alert' => $message, 'sound' => 'default');
    $fields = array('device_tokens' => $gcm_ids, 'data' => $message, 'aps' => $aps);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_SSLCERT, $cert);
    //curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $passphrase);
    curl_setopt($ch, CURLOPT_SSLKEY, $cert);
    curl_setopt($ch, CURLOPT_SSLKEYPASSWD, $passphrase);
    curl_setopt($ch, CURLOPT_CERTINFO, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));

    $result = curl_exec($ch);
    if ($result === FALSE) {
        die('Curl failed: ' . curl_error($ch));
    }
    curl_close($ch);
    echo json_encode($result);
}
4

1 回答 1

3

我没有仔细阅读你的问题。

您正在尝试通过 HTTPS 请求向 Apple 发送推送通知。那是行不通的。Apple 推送通知仅适用于 TCP 协议上的特定二进制格式。

作为提供者,您通过二进制接口与 Apple 推送通知服务进行通信。该接口是供提供商使用的高速、大容量接口;它结合二进制内容使用流式 TCP 套接字设计。二进制接口是异步的。

您的代码有很多问题:

您似乎将 GCM 代码与 APNS 代码混合在一起。 $fields = array('device_tokens' => $gcm_ids, 'data' => $message, 'aps' => $aps);看起来与向 Google Cloud Messaging 服务器发送消息时所做的类似。但是 GCM 与 APNS 完全不同,那你为什么认为它会起作用呢?

您正在发送 JSON 正文,这适用于 GCM,但 APNS 使用二进制格式。虽然发送到 APNS 的二进制消息中的有效负载包含一个编码的 JSON 字符串(看起来与您的$apsJSON 相似),但您不能将它打包到另一个 JSON 中并期望它能够工作。

并且https://在 APNS 服务器前面添加不能使其支持 HTTPS,因为它没有实现支持 HTTPS(也不支持 HTTP)。

我建议你使用stream_context,它有效。

于 2013-11-06T15:05:01.363 回答