APN 节点:加载 PEM 文件时出错
Posted
技术标签:
【中文标题】APN 节点:加载 PEM 文件时出错【英文标题】:APN-Node: Error when loading PEM file 【发布时间】:2014-12-25 01:44:44 【问题描述】:我正在尝试让apn-node 推送到我的设备。服务器托管在 Heroku 上,所以我不想提交文件。另外,我不想从远程服务器获取它,而是将它放在环境变量中。
我已经尝试了以下方法 (source):
我从 Apple 创建并下载了证书,现在将它放在我的钥匙串中。我将其导出为*.p12
文件,并使用openssl pkcs12 -in dev.p12 -out dev.pem -nodes
将其转换为*.pem
文件。
为了设置环境变量,我做了export APN_CERT="$(cat dev.pem)"
。当我在我的应用程序中打印出来时,它显示证书非常好。
但是,当我实际发送通知(并且 node-apn 打开连接)时,它会抛出 [Error: wrong tag]
。
此错误是由加密模块发出的:
apn Raising error: +4ms [Error: wrong tag] undefined undefined
apn Error occurred with trace: +1ms Error: wrong tag
at Object.exports.createCredentials (crypto.js:176:17)
at Object.exports.connect (tls.js:1344:27)
at apnSocketLegacy
该模块还抛出一个APN transmission error: moduleInitialisationFailed (Code: 513)
。
我找不到任何有用的信息,除了这可能与节点本身的加密模块本身有关。这就是为什么我怀疑我在创建证书时做错了什么,但感谢任何指导建议。
【问题讨论】:
【参考方案1】:我为 apns-sharp 找到了 this guide,它实际上描述了如何生成有效的 .p12 文件。
不过,将其写入环境变量并不起作用。我的阅读代码是:new Buffer(certString, 'binary')
,但我认为它仍然没有以正确的格式提供。
我的解决方案是通过fs.readFileSync
直接从文件中读取缓冲区。
要使 env 变量工作,您可以通过 cat cert.p12 | base64
对文件进行编码,然后使用 new Buffer(certString, 'base64')
将其加载。这终于对我有用了。
【讨论】:
要确保您的 base64 没有换行符,请使用base64 -w 0
。我最终使用cat cert.p12 | base64 -w 0 | clipit
对其进行编码并将其直接复制到剪贴板。【参考方案2】:
这里的首选是使用与应用程序一起存储的加密 p12,并指定您通过环境变量设置的密码。
我无法使用以下脚本复制您的问题
var apn = require("apn");
var token = "<token>; // iPad
var service = new apn.connection(
cert: process.env.APN_CERT, key: process.env.APN_KEY
);
service.on("connected", function()
console.log("Connected");
);
service.on("error", function(err)
console.log("Standard error", err);
);
function pushNotification()
var note = new apn.notification().setAlertText("Hello");
service.pushNotification(note, token);
service.shutdown();
pushNotification();
运行:
$ export APN_CERT=$(cat certificates/cert.pem)
$ export APN_KEY=$(cat certificates/key.pem)
$ node apn-env.js
您看到的错误"wrong tag"
来自 OpenSSL,表明证书数据本身中包含的数据存在解析错误,而不是从环境中错误加载的数据。从环境变量加载 PEM 文件正常工作
【讨论】:
好的,我很想看看你能不能找到什么。【参考方案3】:var apn = require("apn");
var deviceToken = "device token";
var service = new apn.Provider(
cert: '.path to /cert.pem', key:'pat to ./key.pem'
);
var note = new apn.Notification();
note.expiry = Math.floor(Date.now() / 1000) + 60; // Expires 1 minute from now.
note.badge = 3;
note.sound = "ping.aiff";
note.alert = " You have a new message";
note.payload = 'messageFrom': 'Rahul test apn';
note.topic = "(Bundle_id).voip";
note.priority = 10;
note.pushType = "alert";
service.send(note, deviceToken).then( (err,result) =>
if(err) return console.log(JSON.stringify(err));
return console.log(JSON.stringify(result))
);
加载 pem 文件并使用令牌运行
【讨论】:
以上是关于APN 节点:加载 PEM 文件时出错的主要内容,如果未能解决你的问题,请参考以下文章
使用 git-tracked heroku 项目时如何安全地存储 .pem 文件?
iOS 7 SpriteKit 游戏 - 保存加载游戏时出错:'尝试将 nil 节点添加到父节点:<SKNode> 名称:'(null)'