使用 HTTPS 進行本機開發作業

在大多數情況下,http://localhost 的行為與 HTTPS 類似,可用於開發。不過,在某些特殊情況下 (例如自訂主機名稱或跨瀏覽器使用安全 Cookie),您需要明確設定開發網站,使其行為與 HTTPS 相同,才能準確呈現網站在實際工作環境中的運作方式。(如果正式版網站未使用 HTTPS,請優先改用 HTTPS)。

本頁說明如何使用 HTTPS 在本機執行網站。

如需簡短操作說明,請參閱 mkcert 快速參考指南。**

使用 mkcert 在本機執行 HTTPS 網站 (建議)

如要透過本機開發網站使用 HTTPS,並存取 https://localhost 或 https://mysite.example (自訂主機名稱),您需要由裝置和瀏覽器信任的實體 (稱為信任的憑證授權單位 (CA)) 簽署的 TLS 憑證。瀏覽器會先檢查開發伺服器的憑證是否由信任的 CA 簽署,再建立 HTTPS 連線。

建議使用跨平台 CA mkcert 建立及簽署憑證。如需其他實用選項,請參閱「使用 HTTPS 在本機執行網站:其他選項」。

許多作業系統都包含用於建立憑證的程式庫,例如 openssl。不過,這些工具比 mkcert 複雜且較不可靠,不一定能跨平台使用,因此較不適合大型開發團隊。

設定

  1. 安裝 mkcert (僅限一次)。

    請按照操作說明,在作業系統上安裝 mkcert。例如,在 macOS 上:

    brew install mkcert
    brew install nss # if you use Firefox
    
  2. 將 mkcert 新增至本機根 CA。

    在終端機中執行下列指令:

    mkcert -install
    

    這會產生本機憑證授權單位 (CA)。mkcert 產生的本機 CA 只在裝置本機上受信任。

  3. 為網站產生憑證,並由 mkcert 簽署。

    在終端機中,前往網站的根目錄或要保存憑證的目錄。

    接著,執行以下指令:

    mkcert localhost
    

    如果您使用的是自訂主機名稱 (例如 mysite.example),請執行下列指令:

    mkcert mysite.example
    

    這個指令會執行兩項作業:

    • 為指定的主機名稱產生憑證。
    • 讓 mkcert 簽署憑證。

    憑證現已就緒,並由瀏覽器在本機信任的憑證授權單位簽署。

  4. 將伺服器設為使用 HTTPS 和您剛建立的 TLS 憑證。

    具體做法取決於您的伺服器。以下提供幾個範例:

    👩🏻‍💻 使用節點:

    server.js (請替換 {PATH/TO/CERTIFICATE...} 和 {PORT}):

    const https = require('https');
    const fs = require('fs');
    const options = {
      key: fs.readFileSync('{PATH/TO/CERTIFICATE-KEY-FILENAME}.pem'),
      cert: fs.readFileSync('{PATH/TO/CERTIFICATE-FILENAME}.pem'),
    };
    https
      .createServer(options, function (req, res) {
        // server code
      })
      .listen({PORT});
    

    👩🏻‍💻 使用 http-server:

    按照下列方式啟動伺服器 (請替換 {PATH/TO/CERTIFICATE...}):

    http-server -S -C {PATH/TO/CERTIFICATE-FILENAME}.pem -K {PATH/TO/CERTIFICATE-KEY-FILENAME}.pem
    

    -S 會使用 HTTPS 執行伺服器,-C 會設定憑證,-K 則會設定金鑰。

    👩🏻‍💻 使用 React 開發伺服器:

    按照下列方式編輯 package.json,並替換 {PATH/TO/CERTIFICATE...}:

    "scripts": {
    "start": "HTTPS=true SSL_CRT_FILE={PATH/TO/CERTIFICATE-FILENAME}.pem SSL_KEY_FILE={PATH/TO/CERTIFICATE-KEY-FILENAME}.pem react-scripts start"
    

    舉例來說,如果您在網站的根目錄中為 localhost 建立了憑證:

    |-- my-react-app
        |-- package.json
        |-- localhost.pem
        |-- localhost-key.pem
        |--...
    

    start 指令碼應如下所示:

    "scripts": {
        "start": "HTTPS=true SSL_CRT_FILE=localhost.pem SSL_KEY_FILE=localhost-key.pem react-scripts start"
    

    👩🏻‍💻 其他範例:

  5. 在瀏覽器中開啟 https://localhost 或 https://mysite.example,再次確認網站是在本機上透過 HTTPS 執行。您不會看到任何瀏覽器警告,因為瀏覽器信任 mkcert 做為本機憑證授權單位。

mkcert 快速參考指引

mkcert 快速參考指引

如要使用 HTTPS 執行本機開發網站,請按照下列步驟操作:

  1. 設定 mkcert。

    如果尚未安裝 mkcert,請先安裝,例如在 macOS 上:

    brew install mkcert

    請參閱安裝 mkcert,瞭解 Windows 和 Linux 的操作說明。

    接著,建立本機憑證授權單位:

    mkcert -install
  2. 建立信任的憑證。

    mkcert {YOUR HOSTNAME e.g. localhost or mysite.example}

    這會建立 mkcert 自動簽署的有效憑證。

  3. 將開發伺服器設為使用 HTTPS 和您在步驟 2 建立的憑證。

現在可以在瀏覽器中存取 https://{YOUR HOSTNAME},不會看到警告

</div>

使用 HTTPS 在本機執行網站:其他選項

以下是設定憑證的其他方法。這些方法通常比使用 mkcert 更複雜或風險更高。

自行簽署的憑證

您也可以決定不使用 mkcert 等本機憑證授權單位,而是自行簽署憑證。這種做法有幾個缺點:

  • 瀏覽器不信任您是憑證授權單位,因此會顯示警告,您必須手動略過。在 Chrome 中,您可以使用 #allow-insecure-localhost 旗標,在 localhost 上自動略過這項警告。
  • 如果您在不安全的網路中工作,這是不安全的。
  • 不一定比使用 mkcert 等本機 CA 更簡單或更快。
  • 自行簽署的憑證與信任的憑證行為不盡相同。
  • 如果您不是在瀏覽器環境中使用這項技術,則必須停用伺服器的憑證驗證功能。如果忘記在正式環境中重新啟用,會導致安全性問題。
使用自行簽署憑證時,瀏覽器顯示的警告螢幕截圖。
使用自行簽署憑證時,瀏覽器顯示的警告。

如未指定憑證,React 和 Vue 的開發伺服器 HTTPS 選項會在背景建立自行簽署憑證。這種做法雖然快速,但會出現相同的瀏覽器警告,以及自行簽署憑證的其他問題。幸好,您可以使用前端架構內建的 HTTPS 選項,並指定使用 mkcert 或類似工具建立的本機信任憑證。詳情請參閱 mkcert 搭配 React 範例。

為什麼瀏覽器不信任自行簽署的憑證?

如果您在瀏覽器中使用 HTTPS 開啟本機執行的網站,瀏覽器會檢查本機開發伺服器的憑證。如果發現憑證是由您自行簽署,系統會檢查您是否已註冊為受信任的憑證授權單位。由於您並非該網站的擁有者,瀏覽器無法信任憑證,因此會顯示警告,告知您連線不安全。如果繼續操作,系統仍會建立 HTTPS 連線,但您必須自行承擔風險。

圖表:為什麼瀏覽器不信任自行簽署的憑證。
為什麼瀏覽器不信任自行簽署的憑證。

由一般憑證授權單位簽署的憑證

您也可以使用由官方 CA 簽署的憑證。這會帶來以下問題:

  • 與使用 mkcert 等本機 CA 技術相比,您需要進行更多設定工作。
  • 請務必使用您控管的有效網域名稱。也就是說,您無法將官方 CA 用於下列用途:
    • localhost 和其他保留網域名稱,例如 example 或 test。
    • 任何您無法控制的網域名稱。
    • 頂層網域無效。詳情請參閱有效的頂層網域清單。

反向 Proxy

另一個使用 HTTPS 存取本機執行網站的方法,是使用反向 Proxy,例如 ngrok。這會帶來下列風險:

  • 只要與他人分享反向 Proxy 網址,對方就能存取您的本機開發網站。這項功能有助於向客戶展示專案,但也可能讓未經授權的使用者分享機密資訊。
  • 部分反向 Proxy 服務會依用量收費,因此價格可能是您選擇服務時的考量因素。
  • 瀏覽器的新安全措施可能會影響這些工具的運作方式。

如果您在 Chrome 中使用自訂主機名稱 (例如 mysite.example),可以使用標記強制瀏覽器將 mysite.example 視為安全。避免這樣做的原因如下:

  • 您必須百分之百確定 mysite.example 一律解析為本機位址。否則,正式環境憑證可能會外洩。
  • 這個旗標僅適用於 Chrome,因此無法跨瀏覽器偵錯。

感謝所有審查人員和貢獻者提供的貢獻和意見回饋,特別是 Ryan Sleevi、Filippo Valsorda、Milica Mihajlija 和 Rowan Merewood。🙌