前言
我们知道,一般而言我们在自己本地调试 Node.js 项目的时候,无一例外都是通过 http://localhost:<port>
后接具体的接口 url 地址来进行接口访问。但是当我们本地开发完成之后,需要在我们自己的服务器上面进行项目的部署,这也就意味着在服务端启动的项目需要使用 http://<服务器公网IP地址>:<后端服务启动端口>
来进行访问。
这样乍一听是不是也没什么问题?但是当我们的前端项目已经部署好,并且已经成功的绑定了 https 与域名,这个时候如果再去访问后端的 http 的接口, 极大概率都会被浏览器本身的安全策略给拦下来,理由是 https 访问 http 类型协议的资源,很容易造成安全隐患。
这个时候我们意识到, 后端的服务不可能永远使用 http+IP 地址的形式进行访问,成熟的项目必将使用 https+域名的形式来访问服务。
因此,在这篇文章中我将给出我为我自己的后端项目配置 https+域名的过程,供有需要参考的同学借鉴学习。
前置准备
既然是需要使用 https+域名,那么 域名 和 启用 https 所需的 SSL 证书 两者都必不可少。
准备一个域名
域名的准备相对比较简单,直接去各大类型的云服务提供商如阿里云、腾讯云、AWS 等去搜索"域名注册",然后输入一个自己喜欢的域名看看能不能买。
一般对于服务器的域名而言,比较常见的是采用 api.example.com
这样格式命名居多(Pixiv 就是这样的格式),我自己使用的是 nonhana-server.cn
,我觉得意思到了即可。
我的域名是在腾讯云进行购买的,所以接下来我的演示会以腾讯云这边为例。
为域名准备 SSL 证书
在上一步购买域名完毕之后,我们进入到腾讯云的SSL 证书管理页面,然后选择我的证书,点击 免费申请证书(默认大家都是白嫖的) 。
腾讯云总共为我们每个个人用户提供了 30 个免费证书的发放额度,我觉得对于我们平时学习使用已经是绰绰有余了。
选择 申请免费证书 ,根据其验证步骤提示一步一步进行验证提交即可。由于我已经通过了验证,所以这边不再进行展示验证的过程。
申请完成,并且审核通过之后,你的域名所对应的证书就可以在 我的证书 一栏查看到了。选择自己对应想要操作的域名证书,点击右侧的下载按钮,打开选择弹窗。
我们在这里选择 Nginx 类型的证书进行下载,包含了 pem、crt 以及 key 文件。我们待会儿要使用的就是 pem 和 key 文件。
把域名绑定到服务器
当然,你购买了域名之后还需要将这个域名解析到对应的服务器上。
进入我的域名页面,然后点击右侧的解析按钮进入目标域名的解析页面,向其中添加主机记录为 @
与 www
的 A
类型域名解析,两条解析对应的 IP 地址都是你的服务器对应的公网访问 IP 地址。
在原生 Express 项目中接入
上述步骤全部完成之后,就可以开始进行在 Express 项目中的接入了。
我们在上述步骤中已经完成了对 ssl 证书的下载,其中包括了 pem 格式以及 key 格式。
首先,我们将这两种格式的证书复制到你的项目的静态资源目录下面。在我个人的项目中就是 /public/ssl
目录下。
然后,我们在服务启动脚本 /bin/server.ts
中,把原本启动服务的方法改写成一个函数。这个函数首先通过环境变量获取当前的环境类型,判断当前项目所处的环境是开发环境(development)还是生产环境(production),如果是开发环境则不启用 https+域名访问;如果是生产环境则采用 https+域名进行访问。最后通过调用这个函数来启动服务,即可。
而具体究竟是怎么启用 https+域名进行访问的呢?这个是怎么实现的呢?这就借助了 express 项目中内置的 https
模块。我们首先在最上方进行这个模块的导入: import https from https
,然后再调用它提供的 createServer()
方法,传入配置项以及 express 项目的核心脚本 app.ts
从而启动服务。而我们的证书,就是在 createServer()
这个方法的第一个参数中传进去的。
具体可以参考一下我自己的实现代码:
typescript
import dotenv from "dotenv";
import http from "http";
import https from "https";
import fs from "fs";
import path from "path";
import app from "../app";
import debug from "debug";
/**
* 读取环境变量配置。
*/
dotenv.config();
// ...其他的配置
/**
* 定义创建 HTTP/HTTPS 服务器的函数:
* 如果是生产环境,则使用 HTTPS 创建服务器,否则使用 HTTP 创建服务器。
*/
function createServer() {
if (process.env.NODE_ENV === "production") {
const options = {
key: fs.readFileSync(
path.join(__dirname, "../public/ssl/nonhana-server.cn.key")
),
cert: fs.readFileSync(
path.join(__dirname, "../public/ssl/nonhana-server.cn_bundle.pem")
),
};
return https.createServer(options, app);
} else {
return http.createServer(app);
}
}
const server = createServer();
// ...其他的配置
在这里我采用的是 dotenv
这个第三方库来实现对 .env
环境变量的读取操作。
我们可以看到,我这边的配置项 options
实际上就是一个对象,里面放了两个属性 key
以及 cert
。 key
对应的就是 .key
格式的证书,而 cert
对应的就是 .pem
格式的证书,直接通过 path 模块进行导入就可以了。
完成之后,我们只要在服务端把 .env
中的 NODE_ENV
字段改为 production,然后再确保证书已经配置 OK,就可以使用 https+域名来进行访问你的后端项目了。