我在应用程序中将财务数据发送给用户的PDF功能导出。我使用测试网站100%工作了此功能,但是当我部署到生产站点时,它无效。在产品网站上,用户通过空白,1KB,1页的PDF文件发送电子邮件(在PDF查看器中可以打开(。
这是我如何使用该功能的低点。我使用本指南使噩梦JS在亚马逊Linux上工作。
- 服务器导出接收
/export
调用 -
称为使用
xvfb-run
创建一个视觉框架缓冲区的儿童过程。exec(`xvfb-run -a --server-args="-screen 0 1366x768x24" node ${path.join(__dirname, 'export.js')} ${process.env.TYPE} ${token} ${req.user.email}`)
-
在Export.js流程中,噩梦JS在网站上运行的端口中的http浏览器负载(测试站点:端口3001,prod站点:3000(。
Nightmare() .viewport(1366, 768) .goto( `http://localhost:${process.env.PORT}/export_summary_1? exportToken=${exportToken}` ) .wait(3000) .pdf() .end() .then(function(pdfBuffer) { mailOptions.attachments = [{ filename: 'financial_model.pdf', content: pdfBuffer }] email.send(mailOptions) })
-
/export_summary_1
浏览器页面进行了另一个服务器调用以加载并使用导出令牌显示财务数据。然后,如上面的代码所示,噩梦将页面捕获到PDF中,最后将PDF发送给用户。
我不相信我的AWS设置是罪魁祸首,因为在AWS实例上,对PDF系统的相关部分全部完成(例如,噩梦页面负载已完成至http://localhost:[port]/export_summary_1
(。
我确实有一个http-> https重定向,但是我可以绕过噩梦页面加载和加载页面的服务器调用以检索财务数据。
即使我不认为问题是我的AWS设置,这是我在 aws和端口设置上的注释,以进行完整。
- 在我的实例使用的我的安全组中启用了两个端口3000和3001。
- 负载平衡器设置
- 端口80和443个听众转发到" EC2-Instance-targets",其AWS实例是注册目标,使用端口3000。
- 端口3001侦听器将AWS实例作为注册目标,使用端口3001。
此外,AWS实例是" EC2-Instance-Targets"视图中的"不健康"注册目标("产品网站"用于" EC2-Instance-targets"(。这是因为,我相信" EC2-Instance-Targets"目标组的端口设置为80,而注册目标的端口设置为3000。
但是,产品网站仍然有效,正如我之前说的,这些AWS/负载平衡器设置似乎不是问题来源。
,尽管我确实计划在几个小时内尝试解决上述方面,而这对我来说是夜间。
此外,我还评论了噩梦加载的页面的电话,以获取财务数据。现在,导出到PDF的加载页面上有" Hello World"文本。问题仍然存在。
如何将导出到PDF功能上的PDF功能?
tldr; airnmarejs加载了一个空白页,该页面已导出到PDF,因为有 https://localhost:3000/bundle.js
和 https://localhost:3000/styles/style.css
的子电话,无法连接(由于HTTPS是通过AWS负载平衡器实现的(。
在我的问题中,我提到了我如何认为出口到PDF处理的部分都在本地完成。实际上就是这种情况,但是进一步的HTTP-> HTTPS正在进行中。这是http-> https重定向代码的外观:
app.use(function(req, res, next) {
if(!req.secure &&
req.get('X-Forwarded-Proto') !== 'https' &&
// above: achieves HTTP->HTTPS redirecting using AWS load balancer and EC2 instance
!/export_summary/.test(req.url)) {
res.redirect('https:' + req.hostname + req.url)
} else {
next()
}
})
// NOTE: all code above is commented out on test site, and uncommented for production site
这是一个stackoverflow页面,说明了如何使用AWS负载平衡器和EC2实例重定向HTTP-> HTTPS,以及上面代码中使用的内容。
当我最初将导出到PDF功能部署到POR网站时,我发现了一个NightMarejs错误,告知我无法达到https://localhost:3000/export_summary
。因此,我将!/export_summary/.test(req.url)
插入了条件,因此NightMarejs的HTTP调用export_summary
页面不会将其重定向到HTTPS调用。
上面的代码块还采用了NightMarejs加载export_summary
页面的子电话。因此,将两个用于资源的主要子呼叫将http://localhost:3000/bundle.js
和http://localhost:3000/styles/style.css
重定向到其HTTPS对应物。(注意:bundle.js调用为 /export_summary
的HTML文件中的<script src='bundle.js'></script>
。
由于在AWS实例上没有设置实际的HTTPS服务器,因此这些子电话无法连接(客户端将其报告为"连接拒绝"错误消息(。该应用程序的HTTP是通过AWS负载平衡器实现的。
这两个资源负责该应用程序的整个内容。因此,没有它们,加载的页面是白色和空白的,如出口PDF所示。
此外,如上所述的代码块中的注释中所述,在测试站点上发表了HTTP-> HTTPS重定向代码。这说明了我如何看待该功能在测试网站上的预期工作,因为令人不安的中间件不是处理的一部分。
解决方案
我更新了绕过http-> https重定向的条件,还包括相关的子呼叫:
!/(export_summary)|(exportPrivate)|(bundle.js)|(style.css)|(.png)|(.ttf)|(.woff)/.test(req.url))
注意:PNG,TTF和WOFF资源调用也需要绕过,因为它们是完整的,抛光的PDF所需的。
最后,我在这里看不到安全风险,尽管我认为当然可以改进安全性。
- bundle.js,style.css和image/font文件中没有保密数据。
- 对于
/export_summary
调用,服务器使用用于部署应用程序的index.html文件响应(也没有机密数据(。 - 绕过包含"导出"子字符串的端点的调用是为了加载导出到PDF的用户数据的呼叫。在任何情况下,由于允许在HTTP上允许呼叫,因此在任何情况下都不会在互联网上使用此呼叫。它只能使用无头客户端浏览器(例如Nightmarejs(在服务器上。
欢迎有关改善解决方案安全方面的任何建议。