在本地开发调试环境使用 HTTPS

做者 LeanCloud weakishhtml

原则上,本地开发调试环境和线上生产环境的差别越小越好。因为目前大多数站点(不管是直接供用户访问的网站仍是提供后端 API 的站点)使用的都是 HTTPS,因此在本地开发调试环境也使用 HTTPS 颇有必要。前端

它不只有助于尽早发现和 HTTPS 相关的一些问题(好比代码中不当心请求了 HTTP 资源,因为本地调试阶段使用 HTTP 协议,因此没有发现,上线后由于混合内容被浏览器阻塞,网站显示异常甚至不能正常工做),也有助于避免一些客户端的限制(好比经过局域网访问站点,测试站点的 service worker 功能)。react

其实在本地配置 HTTPS 很是快捷方便,有现成的成熟工具可使用。大体分两步:git

  1. 生成证书。
  2. 修改项目的启动服务。

生成证书

咱们将使用 [mkcert] 这个零配置的命令行工具生成证书。github

首先安装 mkcert。macOS 下可使用 Homebrew 安装,其余系统请参考 mkcert 的文档shell

brew install mkcert
brew install nss

其中,nss 是可选的,若是不使用或者不须要测试 Firefox,那么能够不安装 nssexpress

接着咱们建立一个目录来存放证书,好比 ~/.certnpm

mkdir -p ~/.cert

自动生成证书:json

mkcert -key-file ~/.cert/key.pem -cert-file ~/.cert/cert.pem "localhost"

让系统信任生成的证书:后端

mkcert -install

由于须要在系统中安装本地 root CA,因此运行上述命令会请求 sudo 权限。只有初次生成证书时须要运行这个命令,后续经过 mkcert -key-file 生成的证书会自动被系统信任。

修改项目的启动服务

许多框架都提供了几乎是开箱即用的 HTTPS 支持,好比在启动命令时加上相应的命令行参数或是环境变量,或者在启动服务的代码中进行简单的配置。下面就之前端开发比较流行的[http-server]、React、[Express] 为例(三者正好对应了前述三种方式),介绍如何在本地开发调试时启动 HTTPS 服务。

http-server

纯静态项目能够经过 [http-server] 进行调试,要切换至 HTTPS 模式,只需加上三个命令行参数:

npx http-server -S -C ~/.cert/cert.pem -K ~/.cert/key.pem

React

经过 Create React App 建立的 React 项目,只需在启动服务时指定几个环境变量就能够切换至 HTTPS 模式:

npx create-react-app example
cd example
HTTPS=true SSL_CRT_FILE=$HOME/.cert/cert.pem SSL_KEY_FILE=$HOME/.cert/key.pem npm start

1

为了省去每次启动都须要在前面加上这几个环境变量的麻烦,能够直接修改 package.jsonscripts.start 项:

"start": "HTTPS=true SSL_CRT_FILE=$HOME/.cert/cert.pem SSL_KEY_FILE=$HOME/.cert/key.pem react-scripts start",

这样,之后只需运行 npm start 便可启动 HTTPS 服务。

Express

相比上述两个项目,[Express] 稍微麻烦一点点,须要简单修改启动服务代码。

首先咱们建立项目目录并安装 expressjs:

mkdir example
cd example
npm init -y
npm i express

而后编写如下简单的启动 HTTPS 服务的示例代码:

const express = require('express')
const app = express()
const https = require('https')
const fs = require('fs')
const os = require('os')
const path = require('path')
const port = 3000

app.get('/', (req, res) => {
  res.send('Hello World!')
})

https.createServer({
    key: fs.readFileSync(path.join(os.homedir(), '.cert/key.pem')),
    cert: fs.readFileSync(path.join(os.homedir(), '.cert/cert.pem'))
}, app).listen(port, () => {
  console.log(`Example app listening at https://localhost:${port}`)
})

能够看到,和 Express 官网上的 Hello World 示例代码相比,咱们另外引入了 https 包,并经过 createServer 方法建立了 https 服务,并指定了证书路径为以前生成的本地证书。

2

反向代理

线上生产环境常见的一种架构是在 HTTP 服务前加一层反向代理,HTTPS 加解密在反向代理层面完成。若是项目的生产环境使用这一架构,那么为了最大限度地与生产环境保持一致,本地开发调试时也能够采起相似的架构,好比使用 [Caddy] 充当反向代理服务器。

macOS 下 Caddy 能够经过 Homebrew 安装,其余系统请参考 Caddy 文档

brew install caddy

正常启动 HTTP 服务后,只需一行命令便可加上反向代理(这里假定服务的端口是 3000):

caddy reverse-proxy --from localhost --to localhost:3000

经过 https://localhost 便可访问服务:

3

Caddy 会自动生成证书,获取系统信任,无需另行生成证书,也无需修改项目的启动服务。

结语

为了保证本地开发调试环境和线上生产环境尽量一致,在本地也使用 HTTPS 颇有必要。这里介绍了两种在本地开发调试阶段使用 HTTPS 的方法,实施起来都很是快捷方便,能够根据项目的具体状况和我的偏好选用。固然,除了在这两种解决问题的方案中选择,也能够选择直接消灭问题,在线上环境进行调试。许多 serverless 云服务都提供线上调试功能,好比 LeanCloud 的云引擎提供和生产环境几乎彻底同样的预备环境,能够自动获取项目 git 仓库的更新并部署到预备环境,调试完成、测试经过后能够一键发布至生产环境,免去在本地搭建环境、配置工具的麻烦。

相关文章
相关标签/搜索