在本地開發調試環境使用 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 倉庫的更新並部署到預備環境,調試完成、測試經過後能夠一鍵發佈至生產環境,免去在本地搭建環境、配置工具的麻煩。

相關文章
相關標籤/搜索