4

是的:这个问题有很多重复,但没有一个答案有帮助。

我正在关注Ali Hafizji 关于使用 APNS 服务进行推送通知的精彩教程

在开发模式下测试 APNS :

  • 下载aps_development.cer
  • 导出证书的私钥 ( aps_development_key.p12)

然后我使用以下命令(使用终端)将两者结合起来:

openssl x509 -in aps_development.cer -inform der -out aps_development.pem
openssl pkcs12 -nocerts -out aps_development_key.pem -in aps_development.p12
cat aps_development.pem aps_development_key.pem > final_aps_development.pem

而且(在服务器上使用 ApnsPHP)我可以使用此配置成功发送推送通知:

...
$push = new ApnsPHP_Push(ApnsPHP_Abstract::ENVIRONMENT_SANDBOX,'final_aps_development.pem');
$push->setRootCertificationAuthority('entrust_root_certification_authority.pem');
$push->setProviderCertificatePassphrase('mypassword');
...

旁注:我从https://github.com/jonathanrcarter/push2press获取了 entrust_root_certification_authority.pem ,寻找它的正确地址可能是https://www.entrust.net/downloads/binary/entrust_2048_ca.cer (无论如何,它们是一样的)。

在这种情况下,应用程序在调试模式下运行(在设备上,从 XCode 运行)并且一切正常。

在生产模式下测试 APNS :

为了在生产模式下测试 APNS,我将应用程序存档以进行 AdHoc 分发,并使用iPhone 配置实用程序将其安装在设备上。

aps_production.cer我对 make遵循了相同的程序final_aps_production.pem

Bang,用于发送推送通知的 php 脚本返回了 HTML 状态码 500。

$push一代当然针对生产模式进行了修改:

...
$push = new ApnsPHP_Push(ApnsPHP_Abstract::ENVIRONMENT_PRODUCTION,'final_aps_production.pem');
$push->setRootCertificationAuthority('entrust_root_certification_authority.pem');
$push->setProviderCertificatePassphrase('mypassword');
...

快速查看/var/log/apache2/error.log表明问题:

PHP Fatal error:  Uncaught exception 'ApnsPHP_Exception' with message 'Unable to connect to 'ssl://gateway.push.apple.com:2195':  (0)' in /var/www/gettapro/mobile/ApnsPHP/Abstract.php:398\nStack trace:\n#0 /var/www/gettapro/mobile/ApnsPHP/Abstract.php(334): ApnsPHP_Abstract->_connect()\n#1  ....

谷歌搜索(有很多人有这个问题)证明是徒劳的。

许多不同的建议,甚至如此奇怪以至于将持有证书的目录的文件权限更改为 775 ......没有一个建议对我有用。

我也尝试过这种改变ApnsPHP/Abstract.php(这里建议:https ://github.com/duccio/ApnsPHP/issues/29 )但没有成功。

$streamContext = stream_context_create(array('ssl' => array(
             //'verify_peer' => isset($this->_sRootCertificationAuthorityFile),
            'cafile' => $this->_sRootCertificationAuthorityFile,
            'local_cert' => $this->_sProviderCertificateFile
        ))); 

那个讨厌的东西ApnsPHP_Exception并没有消失。

当然,我还确保在测试生产模式时使用了正确的设备 APNS 令牌——调试和生产模式下的设备 APNS 令牌不一样

Anyway: tokens can not be a problem since my notification sending script can't even connect to ssl://gateway.push.apple.com:2195.

Tried to connect ssl://gateway.push.apple.com:2195 via telnet just to make sure: connection was fine.

It became obvious: it is a certificate problem.

4

1 回答 1

8

It seems that aps_production.cer shouldn't be handeled the same way as aps_development.cer

Here comes the RTM moment.

Download and install certificate in the keychain (double clicking aps_production.cer)

Export a .p12 version of aps_production certificate (you also set a password here) from the Keychain Access.

Convert it to .pem format using this command (you will have to enter password here):

openssl pkcs12 -in aps_production.p12 -out final_aps_production.pem -nodes

And voilà - everything started working and i am a happy camper again.

There are great tutorial-like instructions by Jeremy on how to export certificate & key here on SO.

于 2013-09-26T15:04:16.963 回答