背景
Node.js用于做小程序后台服务,域名要求必须是Https协议。在Node.js开启Http服务是非常简单的,如下:
const http = require('http'); const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/html;charset=utf8' }); res.end('访问成功') }); server.listen(8080, () => { console.log('服务已开启'); })
如果想使用Https服务需要两步:1. 需要有一份SSL证书;2. 使用Node.js自身的Https模块。
SSL证书
获取SSL证书方式有两种:
- 自己借助openSSL工具生成SSL证书(比如:Let’s Encrypt)
- 下载某些平台提供的免费/付费的SSL证书(推荐)
我是使用某云平台提供免费的证书
点击下载后选择服务器类型
下载后的文件分别是以.key、.pem
为后缀,其中.key
文件是base64加密私钥,.pem
文件是base64加密的证书。
使用Node.js自身的Https模块开启一个服务
相较Http,它多了一个options参数。
const https = require('https'); const fs = require('fs'); const path = require('path'); const options = { key: fs.readFileSync(path.join(__dirname, './ssl/9499016_www.linglan01.cn.key')), cert: fs.readFileSync(path.join(__dirname, './ssl/9499016_www.linglan01.cn.pem')), }; const server = https.createServer(options, (req, res) => { res.writeHead(200, { 'Content-Type': 'text/html;charset=utf8' }); res.end('访问成功') }); server.listen(8080, () => { console.log('服务已开启'); })
由于SSL证书我绑定的域名是www.linglan01.cn, 当我使用https://127.0.0.1:8080 访问服务时与绑定的域名不相符,它会被拦截访问,仅允许www.linglan01.cn访问。
SSL/TLS证书并不是绑定在端口上,而是绑定在服务器的IP地址和域名上。服务器可以使用任何端口来提供HTTPS服务,通常情况下,HTTPS使用443端口来提供服务,这是因为443端口已经被IANA注册为HTTPS默认端口。
使用Express框架开启Https
工作中肯定是使用社区的Express等框架进行开发,想在Express等框架中开启Https也非常容易,以Express举例:
const https = require('https'); const fs = require('fs'); const path = require('path'); const express = require('express') const app = express(); app.get('/chat', (req, res) => { res.send('我是https') }); const options = { key: fs.readFileSync(path.join(__dirname, './ssl/9499016_www.linglan01.cn.key')), cert: fs.readFileSync(path.join(__dirname, './ssl/9499016_www.linglan01.cn.pem')), }; const server = https.createServer(options, app); server.listen(8080, () => { console.log('服务已开启'); })
我的例子
比如我的域名是92it.top, 我申请了Let’s Encrypt的证书。
SSL端口用的8081
server.js
访问 https://92it.top:8081/chat