我的个人博客

如何在本地创建 HTTPS 服务器?

Black iphone 5 beside brown framed eyeglasses and black iphone 5 c
Published on
/8 mins read/---

什么时候我们需要在本地使用 HTTPS

问题

在大多数情况下,我们在本地开发应用程序时不需要 HTTPS。但是,如果你的应用程序有需要与第三方进行身份验证的功能, 或者需要监听来自其他应用程序的网络钩子...而这些第三方要求你的应用程序必须采用 HTTPS 才能接收他们的请求,那么你该怎么办?

当然,在生产环境中会使用 HTTPS,但如何在本地开发应用程序时拥有安全连接呢?

我们有几个选择,比如使用 PageKitengrok 创建指向你的本地主机HTTPS 隧道, 但这些服务有一些缺点:

  • 免费计划一次可以使用的隧道/请求数量有限。

  • 无法使用特定的域名,每次都会不同,我们必须在每次开发应用程序时重新配置应用程序的环境变量。

  • 而且它们非常,这会浪费大量开发/测试应用程序的时间。

如果你面临类似的问题,这里有解决方案

解决方案

这里的解决方案是使用 OpenSSL 生成 SSL 证书,并使用这些证书创建 HTTPS 服务器。

生成根 SSL 证书

首先,我们需要创建一个根 SSL 证书,用于签署我们将用于本地主机的任何证书。

使用以下命令创建一个 key,以便在下一步中生成根 SSL 证书

openssl genrsa -des3 -out rootCA.key 2048
root-ca-key

系统会要求你输入一个密码短语来生成密钥,只需输入一个随机字符串并验证它。

记住这个密码短语,因为你在接下来的步骤中会需要它!

生成的密钥将保存在 rootCA.key 文件中,使用它通过以下命令生成根 SSL 证书

openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 7300 -out rootCA.pem
root-ca-pem

填写所需信息(密码短语必须与第一步中用于生成 rootCA.key 的密码短语相匹配!)

此证书将保存在 rootCA.pem 文件中。

信任根 SSL 证书

要使用由根 SSL 证书生成的证书,我们需要告诉操作系统信任根证书

打开钥匙串访问应用程序(MacOS),选择证书选项卡:

keychain-access

通过拖拽或导航到**文件 / 导入项目...**导入 rootCA.pem

然后在导入的证书上右键点击 / 获取信息(或双击

cert-trust-setting

展开信任选项卡,在第一个设置中选择始终信任,然后保存。

钥匙串访问将显示一条消息,如**"此证书被标记为此帐户信任",这意味着你已成功信任根 SSL 证书**

创建本地 SSL 证书

现在,我们将使用受信任的根 SSL 证书生成一个用于本地主机SSL 证书

步骤 1

创建一个名为 server.csr.cnf 的配置文件,内容如下。OpenSSL 将使用此文件生成证书密钥

server.csr.cnf
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
 
[dn]
C=US
ST=RandomState
L=RandomCity
O=RandomOrganization
OU=RandomOrganizationUnit
emailAddress=hello@example.com
CN = localhost

使用上述配置创建证书密钥并将其保存到 server.key 文件:

openssl req -new -sha256 -nodes -out server.csr -newkey rsa:2048 -keyout server.key -config <( cat server.csr.cnf )
server-key

步骤 2

创建一个 v3.ext 文件,其中包含以下配置,用于生成证书:

v3.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
 
[alt_names]
DNS.1 = localhost

使用根 SSL 证书v3.ext 配置文件生成证书,然后使用此命令保存到 server.crt

openssl x509 -req -in server.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 825 -sha256 -extfile v3.ext

记得使用与上述步骤中相同的密码短语!

server-cert

完成

现在,在你刚刚创建证书的文件夹中将包含 2 个文件:server.keyserver.crt。我们将在下一步中使用这些文件创建 HTTPS 服务器。

cert-folder

创建 HTTPS 服务器

生成 server.keyserver.crt 的最重要工作已经完成,现在让我们使用该证书在本地使用 Koa.js 创建一个 Node.js HTTPS 服务器 (在 Express 中几乎相同,因为 Koa 是由 Express 背后的团队创建的 )。

使用 Koa 创建一个简单的网络服务器

server.js
let Koa = require('koa');
let app = new Koa();
 
app.use(async ctx => {
  ctx.body = 'Hello World';
});
 
module.exports = app

在你的应用程序中创建一个名为 certs/ 的目录,然后将 server.keyserver.crt 移动到那里。

加载证书文件并使用 https 模块创建 HTTPS 服务器:

index.js
let app = require('./server')
let https = require('https')
let fs = require('fs')
let path = require('path')
 
let certOptions = null
try {
  certOptions = {
    key: fs.readFileSync(path.resolve('certs/server.key')),
    cert: fs.readFileSync(path.resolve('certs/server.crt'))
  }
} catch(err) {
  console.log('No certificate files found!')
}
 
let host = process.env.APP_URL || 'localhost'
let isLocal = host === 'localhost'
let enableHTTPSInLocal = Boolean(isLocal && certOptions)
 
let port = enableHTTPSInLocal ? 443 : process.env.PORT || 3434
let protocol = (isLocal && !certOptions) ? "http" : "https"
 
let url = `${protocol}://${host}${isLocal ? `:${port}` : ''}`
 
let callback = () => {
  console.log(`App start successfully at ${url}`)
}
 
if (enableHTTPSInLocal) {
  https
    .createServer(certOptions || {}, app.callback())
    .listen(port, callback)
} else {
  app.listen(port, callback)
}

项目结构应该如下所示:

https-koa-project

使用 npm start 启动你的应用程序( 注意,是 node index.js,而不是 node server.js!)

http-koa

如果不存在证书文件,应用程序将以普通的 http 启动。

https-koa

在移入证书文件后,应用程序将在端口 443 上以 https 启动。

localhost-443

在浏览器中打开 https://localhost:443,你将看到你的应用程序正在使用 HTTPS 运行

源代码可以在这个仓库中找到。

结论

如果你不是 Node.js 开发者,那么你可以搜索如何在你喜欢的技术中使用证书文件创建 HTTPS 服务器

我希望这个指南能帮助你在本地使用 HTTPS 开发你的应用程序!

分享愉快

参考资料