使用 PEM 文件在 PHP 中推送通知
Posted
技术标签:
【中文标题】使用 PEM 文件在 PHP 中推送通知【英文标题】:Push Notification in PHP using PEM file 【发布时间】:2015-03-29 01:30:50 【问题描述】:我一直在阅读 Ray Wenderlich 的关于使用 php 脚本的推送通知的教程。
参考:http://www.raywenderlich.com/32960/apple-push-notification-services-in-ios-6-tutorial-part-1
http://www.raywenderlich.com/32963/apple-push-notification-services-in-ios-6-tutorial-part-2
我进行了大量研究,但在第 2 部分中遇到了一个问题,您使用 ck.pem 文件运行 push.php 文件。
/Applications/XAMPP/bin/php push.php development
我唯一的区别是我使用的是 XAMPP 而不是 MAMP。
我已确认已安装所有扩展程序。
我可以通过这样做在终端中测试我的证书:
openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushChatCert.pem -key PushChatKey.pem
它要求我输入密码,我输入了。一切都在终端中成功运行。
但是,当我运行 push.php 文件时,出现以下错误:
PHP 警告:stream_socket_client():SSL 操作失败,代码为 1。OpenSSL 错误消息: 错误:14090086:SSL 例程:SSL3_GET_SERVER_CERTIFICATE:证书验证失败 PHP 警告:stream_socket_client(): 无法启用加密
PHP 警告:stream_socket_client():无法在第 140 行连接到 ssl://gateway.sandbox.push.apple.com:2195(未知错误)
php文件中的第140行是:
$this->fp = stream_socket_client('ssl://' . $this->server, $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
我找到了这些:
iOS push notification does not work when using crontab scheduler
https://devforums.apple.com/message/1054840#1054840
Push notification in PHP
我确实重试了所有内容。我知道我的密码是正确的。我重新创建了我的证书、pem 文件和密钥。没有任何效果。每次我这样做时都会出现同样的错误。
我很困惑。
有没有人有任何建议或知道发生了什么?
谢谢!
更新 1:
我还尝试设置 ck.pem 文件的完整路径,但也无法修复错误。
【问题讨论】:
您确定您的 .p12 导出正确吗?从钥匙串导出私钥时,请确保您使用了私钥,而不仅仅是公钥 @Emilie 我只导出了私钥。我没有导出公钥,因为教程也没有告诉我。$ctx
的值是多少,上面设置了哪些选项?
@oflannabhra 选项集:stream_context_set_option($ctx, 'ssl', 'local_cert', $this->certificate); stream_context_set_option($ctx, 'ssl', 'passphrase', $this->passphrase); $ctx 打印出 Resource id #9 当然,我不知道这是什么意思。
$this->certificate
应该是您本地证书的绝对文件路径。
【参考方案1】:
好吧,我终于想通了!经过2天的工作。
因此,对于遇到此问题的其他人:
从以下网址下载 entrust_2048_ca.cer 证书: https://www.entrust.com/get-support/ssl-certificate-support/root-certificate-downloads/
向下滚动并获取 Entrust.net 证书颁发机构 (2048)
然后,在 push.php 文件中,设置密码短语的上下文后,添加以下行:
stream_context_set_option($ctx, 'ssl', 'cafile', 'entrust_2048_ca.cer');
【讨论】:
帮助很大! 答案中的 URL 现在已损坏。此时正确的是 entrust.com/get-support/ssl-certificate-support/… 并向下滚动到 Entrust.net Certificate Authority (2048)。 我希望我能在 5 小时前找到您的帖子!我一直在尝试一切。我注意到如果我从脚本工作的 url 中删除了“ssl://”,但我从未在我的 iPhone 上收到推送通知。我遇到有人说要添加 stream_context_set_option($ctx, 'ssl', 'verify_peer', false);这会破坏服务器验证。作为一个故障排除的想法,我尝试了它,然后推送成功了。那时,我知道问题出在服务器验证上。早些时候,我已经下载了委托证书并将其添加到我的系统钥匙串中,但这并没有帮助。真是太感谢你了!!! 非常感谢!在 MacOS Sierra 中,这是解决方案! 如果可以的话,我会两次支持你的答案。我被困在这个问题上几天了,我开始把头发扯下来。非常感谢!【参考方案2】:已更新至 macOS Sierra 10.12.4
问题出在 macOS Sierra 中的新 PHP 版本。 他们改变了使用证书的方式。
我建议对已接受的答案进行一些小改动,以使事情变得明确。
在创建流上下文时,您必须设置路径到entrust_2048_ca.cer 和其他参数,例如
$streamContext = stream_context_create([
'ssl' => [
'verify_peer' => true,
'verify_peer_name' => true,
'cafile' => '/path/to/bundle/entrust_2048_ca.cer',
]
]);
The full explanation and links are here
【讨论】:
【参考方案3】:更新到 macOS sierra 10.12.5
请补充
stream_context_set_option($ctx, 'ssl', 'verify_peer', false);
问题出在 macOS Sierra 的新 PHP 版本中
【讨论】:
【参考方案4】:添加
stream_context_set_option($ctx, 'ssl', 'verify_peer', false);
这会导致服务器验证失败。 在上面的评论中感谢@百万分之一的应用程序。
【讨论】:
以上是关于使用 PEM 文件在 PHP 中推送通知的主要内容,如果未能解决你的问题,请参考以下文章
我们应该在服务器上使用哪个文件来推送通知,.pem 还是 .p12?