我想得到 节点 来推送到我的设备上。服务器托管在Heroku上,所以我不想提交文件。另外,我也不想从远程服务器上获取文件,而是把它放在一个环境变量中。
我已经尝试了以下方法(源头): 我从苹果公司创建并下载了证书 现在它已经在我的钥匙链里了。我把它导出为 *.p12
文件,并将其与 openssl pkcs12 -in dev.p12 -out dev.pem -nodes
变成 *.pem
文件。
为了设置环境变量,我做了 export APN_CERT="$(cat dev.pem)"
. 当我在我的应用程序中打印出来时,它完美地显示了证书.然而,当我实际发送一个通知(和node-apn打开连接),它抛出一个 [Error: wrong tag]
. 这个错误是由crypto模块发出的。
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)
.
我无法找到任何有用的信息,除了这可能与节点本身的加密模块本身有关。这就是为什么我怀疑我在创建证书时做错了什么,但感谢任何指导性的建议。
我发现 本指南 的apns-sharp,它实际上描述了如何生成一个有效的.p12文件。
不过,把它写进环境变量里还是不行。我读取它的代码是。new Buffer(certString, 'binary')
但我认为它仍然没有以正确的格式提供。
我的解决方案是直接从文件中读取缓冲区,通过 fs.readFileSync
.
为了让env变量发挥作用,你可以通过以下方式对文件进行编码。cat cert.p12 | base64
并将其加载为 new Buffer(certString, 'base64')
. 这终于为我工作了。
在这里,我更倾向于使用存储在应用程序旁边的加密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文件可以正常工作
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文件,并使用令牌运行。