用 NGINX + EXPRESS + Let’s Encrypt 构建HTTPS接口服务
最近想搞个小程序,需要查询下github的api服务。小程序的请求是走的小程序提供的api,没有跨域问题,不过需要配置下请求域名白名单。
本以为可以在小程序后台配置一下域名之后直接请求,结果发现小程序后台配置里只允许设备案过的域名,GitHub显然不可能有国内备案。
还好自己也有服务器+域名,自己动手搭一个。而且小程序要求全是HTTPS的,还是有遇到一点小坑。
方案
其实NGINX本身就可以完成反向代理功能,不过考虑到以后可能还想在这个基础上做一些别的东西,还是来个可编程的服务比较好。出于简便性考虑直接无脑选了express。
开个新的二级域名,因为只有一台云虚拟机,80/443端口已经被NGINX占用了,那就NGINX转发给express吧,所以整个结构就是NGINX反向代理express(这个express服务又是个对github的反向代理,真巧……)
NGINX加一个新配置,监听80端口,对 / 全转发去本机的3000端口,完事。
1 | server { |
然后用Let’s Encrypt搞一下HTTPS,用 certbot 这个工具,直接选服务器软件和系统,可以自动帮你完成配置HTTPS。
用express写个hello world,再全局安装pm2,启动我们的express程序,访问域名即可看到hello world,基本搞定。接下来再选个反向代理中间件,配置下target为api.github.com,大功告成。
超时
结果接下来实际测试发现炸了……
很多请求报504 网关超时
一通搜索,发现很多是给NGINX和PHP结合的方案用的(后仰:什么叫全宇宙最好的语言啊),不过差不多,都是说设置上游超时时间。
创建 /etc/nginx/conf.d/timeout.conf
,加上以下内容:
1 | proxy_connect_timeout 600; |
然后再试,发现还是容易出现504。
就需要细节排查问题了,先查nginx的日志,access.log和error.log,发现这个504在nginx的错误日志里是没有的,access里有记录express程序给返回了200和504,问题应该是出在express里。
接下来打印pm2的日志,发现错误信息是 Error occurred while trying to proxy request xxxxx from 127.0.0.1:xxxx to https://api.github.com (ECONNREFUSED) (https://nodejs.org/api/errors.html#errors_common_system_errors)
打开这个链接,这个错误信息是:ECONNREFUSED (Connection refused): No connection could be made because the target machine actively refused it. This usually results from trying to connect to a service that is inactive on the foreign host.
目标机器主动拒绝了请求,这说明Github应该是觉得这个请求不正常,想了下估计是没带一个浏览器的头,伪装成浏览器应该就好。
配置下代理的headers,再重启服务,终于OK了