使用 mkcert 在本地端實現 HTTPS（以 Node.js, Nuxt.js, Vue Cli 及 create-react-app 為例）
By: Eason Lin
Tags: React, Nodejs, Https, Vue, Nuxtjs

今天偶然在 Medium 首頁看到了一篇如何透過 mkcert 在本地端實現 HTTPS 連線的文章，決定整理一下記錄在這邊。

安裝

若是使用 Mac 環境，可透過 Homebrew 直接安裝，僅需照著官方文件輸入以下指令即可：

brew install mkcert

brew install nss # if you use Firefox

若是使用 Windows 環境，可使用 Chocolatey，若沒安裝 Chocolatey，可透過系統管理員開啟 PowerShell，

並輸入以下指令：

Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString(' https://community.chocolatey.org/install.ps1' ))

完成安裝後，即可透過 choco install mkcert 完成 mkcert 的安裝，最後輸入：

mkcert -install

建立一個本地的憑證頒發機構 (Certificate authority)

Node.js

以 Express Generator 產出的 app 為例，在專案根目錄下使用終端機輸入：

mkcert localhost

接著修改 bin 資料夾中的 www 將 http 模組改為 https ，並將 mkcert 產出的 .pem 檔加入設定，完成後會如下：

#!/usr/bin/env node /**

* Module dependencies.

*/ var app = require("../app");

var debug = require("debug")("myapp:server");

var fs = require("fs");

var https = require("https"); // 改為 https /**

* Get port from environment and store in Express.

*/ var port = normalizePort(process.env.PORT || "3000");

app.set("port", port); /**

* set HTTPS certification -> 新增此設定

*/

const options = {

key: fs.readFileSync("./localhost-key.pem"),

cert: fs.readFileSync("./localhost.pem"),

}; /**

* Create HTTP server.

*/ var server = https.createServer(options, app); // 將設定加入 createServer 方法中 /**

* Listen on provided port, on all network interfaces.

*/ server.listen(port);

server.on("error", onError);

server.on("listening", onListening); /**

* Normalize a port into a number, string, or false.

*/ function normalizePort(val) {

var port = parseInt(val, 10); if (isNaN(port)) {

// named pipe

return val;

} if (port >= 0) {

// port number

return port;

} return false;

} /**

* Event listener for HTTP server "error" event.

*/ function onError(error) {

if (error.syscall !== "listen") {

throw error;

} var bind = typeof port === "string" ? "Pipe " + port : "Port " + port; // handle specific listen errors with friendly messages

switch (error.code) {

case "EACCES":

console.error(bind + " requires elevated privileges");

process.exit(1);

break;

case "EADDRINUSE":

console.error(bind + " is already in use");

process.exit(1);

break;

default:

throw error;

}

} /**

* Event listener for HTTP server "listening" event.

*/ function onListening() {

var addr = server.address();

var bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port;

debug("Listening on " + bind);

}

如果成功的話，可以透過瀏覽器進入 https://localhost:3000

大功告成！

Nuxt.js

在目錄中產出 .pem 檔後，在 nuxt.config.js 中引入 path, fs 模組，並在 server 中加入設定，設定如下：

import path from "path";

import fs from "fs";

export default {

//...

server: {

https: {

key: fs.readFileSync(path.resolve(__dirname, "localhost-key.pem")),

cert: fs.readFileSync(path.resolve(__dirname, "localhost.pem"))

}

}

}

Vue-Cli

在目錄中產出 .pem 檔後，在 vue.config.js （如果沒有就新增一個）加入以下設定：

// vue.config.js

const fs = require("fs");

module.exports = {

devServer: {

https: {

key: fs.readFileSync(`${__dirname}/localhost-key.pem`),

cert: fs.readFileSync(`${__dirname}/localhost.pem`),

},

},

};

啟動伺服器後應該能進入 https://localhost:8080

create-react-app

在目錄中產出 .pem 檔後，在 package.json scripts 區塊修改啟動的指令，例如：

“scripts”: {

“start”:

“HTTPS=true SSL_CRT_FILE=localhost.pem SSL_KEY_FILE=localhost-key.pem react-scripts start”

}

啟動伺服器後應該能進入 https://localhost:3000

什麼情況可以派上用場

有些功能在實作上可能會被要求在 HTTPS 環境下才能實現，在我自己的工作項目上，Facebook Login 就是一個很好的例子，只要將 Callback URL 加入 https://localhost:3000 ，即可輕鬆在本地測試 Facebook 登入。其他好處則可直接參考我在 Reference 中提及的文章。

關於在本地實現 HTTPS 的做法就記錄到這，希望可以幫助到有需要的人，若內文有任何錯誤，也煩請不吝指出，謝謝。

References:

延伸閱讀：