macOS + node.js + BrowserSync でローカルhttps開発環境

## はじめに

この記事は、以下の環境で、https通信可能なローカル開発環境を構築する手順を共有するためのものです。

### 前提とする環境

* macOS v10.13.6
* node.js v8.11.4
* browser-sync v2.24.5

ServiceWorkerに興味があり、実験環境を構築しようとしたところ、httpsが必須とのことでした。
そこで、node.jsの開発環境でhttpsが利用できるように自己証明書を発行し読み込ませます。

**2018/09/08追記**

ServiceWorkerの実行にはhttps通信が必須ですが、**localhostに限りhttp通信でも実行可能**です。

[Service Worker の紹介 - Web Fundamentals](https://developers.google.com/web/fundamentals/primers/service-workers/?hl=ja#https)

Service Worker以外で、localhostに自己証明書が必要になった場合は本記事の方法を試してみてください。

## 設定の手順

基本的に自己証明書の発行と管理にはopensslを利用するのですが、
macの場合GUI操作が可能な`キーチェーンアクセス.app`というユーティリティを利用します。

より詳しい手順の解説はこちらをご参照ください。

[キーチェーンアクセスで自己証明書を作成しローカルSSLサーバーを立ち上げる](https://qiita.com/Limage/items/3cc412e3710e1ce085eb)

## 証明書の作成

まずは`キーチェーンアクセス.app`を起動し`証明書を作成…`を開始します。

![](https://www.evernote.com/l/AAlz1hvtb25BfrteYBXVMxP1PWogCL9M4yQB/image.png)

### 設定

ウィザードが立ち上がりますので、順次設定を行なっていきます。

![](https://www.evernote.com/l/AAlz5x4j9mZHqKM6bYGzr6Izg7zu1wYyHMUB/image.png)

名前はニックネームです。自分がわかりやすい名前を設定して良いです。
証明書のタイプはSSLサーバーを選んでください。
`デフォルトを無効化`チェックをONにしてください。

`続ける`を押すと自己証明書に関する警告が表示されますが、そのまま続行します。

証明書に記載される個人情報を設定します。外部に公開するものではないので、他の証明書と混同しない程度に項目を埋めます。

![](https://www.evernote.com/l/AAnq0YbEfppA_JTl0Nm1-n2mo2fenlBaE6AB/image.png)

次に`鍵ペア情報`という設定画面が出ますが、これはデフォルト設定のままで構いません。

`鍵用途拡張領域`設定画面では`署名`と`鍵の暗号化`にチェックを入れます。

![](https://www.evernote.com/l/AAnz7Na7E1dEDpTys4DkFyqa-Ad-SzBSpNsB/image.png)

`拡張鍵用途拡張領域`設定画面では、`SSLサーバー認証`にチェックを入れます。

![](https://www.evernote.com/l/AAllOCSZC5RFi71eoUKkNDYbuKqjD7AdRlwB/image.png)

`基本制約拡張領域`設定画面では、チェックを入れないでそのまま`続ける`で進みます。

`サブジェクト代替名拡張領域`設定画面では下の2つに`localhost`と`127.0.0.1`をそれぞれ設定します。

![](https://www.evernote.com/l/AAli4B_R3iJNgJ3DXkKE_RkJRysCW0aG-I8B/image.png)

これで自己証明書ができました。

### 自己証明書の許可

作成した証明書を常に信頼するようにOSに設定します。

作成した証明書を右クリックし`情報を見る`メニューを選択します。

![](https://www.evernote.com/l/AAkZowuRLGhOJ5UQg9_96z2Jc5JozSKBiaIB/image.png)

`この証明書を使用するときに`のプルダウンメニューを`常に信頼`に変更します。

![](https://www.evernote.com/l/AAkP_r9A73lFQJsX2HCCeob73v1OgiCS9DMB/image.png)


### 証明書の書き出し

ここまでの手順で作成した証明書から`.cer`および`.p12`ファイルを書き出します。

![](https://www.evernote.com/l/AAk47FREA5RB47vVM9SzJOn8hLqHa6fEYwYB/image.png)

証明書を右クリックすると書き出しメニューが呼び出せます。
ここで`.cer`および`.p12`ファイルの2つをそれぞれ書き出します。

この例では、ユーザーディレクトリ直下に`etc/ssl`というディレクトリを作成して書き出したファイルを保存しました。

書き出し時にパスフレーズを要求されますので、設定したフレーズをメモしておいてください。
すぐに外してしまうので、強固なフレーズを設定する必要はありません。

### 書き出した証明書ファイルの変換

書き出した`.cer`および`.p12`ファイルを`.crt`と`.key`ファイルに変換します。
作業にはターミナルを使用します。

```bash
$ cd ~/etc/ssl 
$ openssl x509 -in *cret.cer* -inform DER -out *cret.crt* -outform PEM
$ openssl pkcs12 -in *key.p12* -nocerts -nodes -out *key.key*
Enter Import Password:
MAC verified OK
```

書き出した証明書ファイルを格納しているディレクトリに移動して作業をしてください。
`*cret.cer*`のように`*`で囲んだ部分がファイル名なので保存したファイル名に合わせて読み替えてください。
`.p12`ファイルの変換には、書き出し時に使用したパスフレーズが必要になります。

## BrowserSyncに自己証明書を渡す

node.js上で稼働するBrowserSyncに、ここまでで作成した証明書、鍵ファイルを渡す必要があります。

node.jsのプロセスからはユーザーディレクトリが取得できますので、これを利用して証明書ファイルまでのパスを通します。

こちらの記事を参考にさせていただきました。

+ [Node.jsでユーザーのホームディレクトリのパスを取得する](https://qiita.com/potato4d/items/7131028497de53ceb48e)
+ [Node.js - Find home directory in platform agnostic way](https://stackoverflow.com/questions/9080085/node-js-find-home-directory-in-platform-agnostic-way)

*▼browsersync.js*

```js
const path = require("path");
const bs = require("browser-sync").create();

const distDir = path.resolve(process.cwd(), "dist");
const userDir = require('os').homedir();
const sslDir = path.resolve(userDir, "etc", "ssl"); // ~/ect/ssl に相当

bs.init({
    server: distDir,
    watch: true,
    https: {
        key: path.resolve(sslDir, "key.key"),
        cert: path.resolve(sslDir, "cret.crt"),
    },
});
```

これでBrowserSyncを`npm run`で起動します。

![](https://www.evernote.com/l/AAmRPLWZ61tJfpq2dmL_7gxH2VyojVorcwgB/image.png)

無事にChromeからhttpsでlocalhostにアクセスできました。証明書も信頼されている扱いで処理されています。BrowserSyncのホットリロード機能も稼働しているようです。

これでServiceWorker開発の準備ができました。
以上、ありがとうございます。