Node.js + APN:在本地,一切正常,但在云主机上启动时出现“端点错误:无法获得本地颁发者证书”

问题描述

我希望能够通过我在智能手机上构建的 React Native 应用程序发送通知。此脚本仅应在服务器启动时向我的设备发送通知

配置

我有一个非常简单的节点 js 服务器,配置如下:

index.js

const app = require('express')();
const http = require('http').Server(app);
const apn = require('apn');



// APNs config

const service = new apn.Provider({
    token: {
        key: 'XXXXXXXXX.p8',keyId: "XXXXXXXXX",teamId: "XXXXXXXXX",},production: process.env.NODE_ENV === 'dev' ? false : true
});

    
// express
app.get('/',(req,res) => res.send('hello world'));


// Listen to port 3000
http.listen(3000,() => console.log('run port :3000'));

然后,我添加了这个方法,它允许我向安装了 React Native 应用程序的设备发送通知

index.js

// on server start,send a notification to my iPhone

const notif = new apn.Notification({
   title: 'Notif said:',alert: 'message'
})

notif.topic = 'com.name.xxxx';
notification.sound = 'ping.aiff';

service.send(notif,'XXXXTOKENDEVICE').then(result => console.log(result))

当我使用命令 NODE_ENV=dev node index.js 在本地运行它时,一切顺利,我在我的设备上收到通知

问题

但是,当我在云主机(Linode、Ubuntu 20.10)上运行它时,它不起作用:我通过 service.send() Promise 收到此消息:

LOG 响应


{
  device: 'XXXXTOKENDEVICE',error: VError: endpoint error: unable to get local issuer certificate
      at Endpoint.<anonymous> (/root/app/node_modules/apn/lib/protocol/endpointManager.js:69:32)
      at Endpoint.emit (events.js:315:20)
      at Endpoint.error [as _error] (/root/app/node_modules/apn/lib/protocol/endpoint.js:149:10)
      at TLSSocket.emit (events.js:327:22)
      at emitErrorNT (internal/streams/destroy.js:92:8)
      at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
      at processticksAndRejections (internal/process/task_queues.js:84:21) {
    jse_shortmsg: 'endpoint error',jse_cause: Error: unable to get local issuer certificate
        at TLSSocket.onConnectSecure (_tls_wrap.js:1501:34)
        at TLSSocket.emit (events.js:315:20)
        at TLSSocket._finishInit (_tls_wrap.js:936:8)
        at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:710:12) {
      code: 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY'
    },jse_info: {}
  }
}

我尝试在生产模式设置为 true 的情况下启动它,但没有任何变化。

我也是与证书等相关的所有内容的初学者。但再一次:一切都在本地工作。我错过了什么吗?或者,我的云服务器是否需要特定配置?

先谢谢你!

解决方法

如果发现这篇文章的人也有同样的问题,我最终的解决方案是降级服务器节点版本(我选择v12.16.2)和socket.io(2.0.3)。

,

您必须在诸如

之类的选项中包含 rejectUnauthorized 为 false
var options = {
     token: {
            key: "./pushcertificates/AuthKey_XXXXXXXXXX.p8",keyId: "XXXXXXXXXX",teamId: "XXXXXXXXXX"
     },production: true,rejectUnauthorized: false
};

文档中提到了这一点。

https://github.com/node-apn/node-apn/blob/master/doc/provider.markdown