vite-plugin-mkcert を使ってNuxtアプリケーションをhttpsで開発する（主に for WSL）

:::note info
viviONグループでは、DLsiteやcomipoなど、二次元コンテンツを世の中に届けるためのサービスを運営しています。
ともに働く仲間を募集していますので、興味のある方は[こちら](#一緒に二次元業界を盛り上げていきませんか)まで。
:::

## きっかけ
nginxの上でNuxtのアプリケーションを動かしてnginxのconfでSSL/TLS化していたのですが、もっと手軽な方法があったため、置き換えた内容です。


## 対象
- Nuxt3で開発してる方 :beginner: 
- 簡単にhttpsで開発したい :beginner: 

## 🪪 mkcertとは

> mkcert is a simple tool for making locally-trusted development certificates. It requires no configuration.

自身のPC内でローカル認証局を作成・インストールしてくれた上、信頼されるサーバー証明書を生成してくれます。
**※本番環境では使用できません**

https://github.com/FiloSottile/mkcert

## :v: vite-plugin-mkcert

mkcertをviteで使いやすいようにしてくれてます。

https://github.com/liuweiGL/vite-plugin-mkcert

今回は、Nuxtアプリケーションを作っていたため、README通りこちらの手順が必要となりました。
```ts
import mkcert from 'vite-plugin-mkcert'

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  vite: {
    plugins: [
      mkcert({
        savePath: './certs', // 証明書を保存するディレクトリ
        force: true, // vite設定にhttpsプロパティがなかった場合も証明書を生成する
        hosts: ['localhost', '127.0.0.1', 'hogehoge.com'] // 必要に応じて対象となるホストを設定
      })
    ]
  },
  devServer: {
    https: {
      cert: './certs/cert.pem',
      key: './certs/dev.pem'
    }
  },
});
```

## :warning: 初回のdevServerの指定について
`nuxi dev` (`nuxt dev`) を実行した際に `vite-plugin-mkcert`が証明書を作成してくれるため、初回は公開鍵・秘密鍵が見つからず、サーバー起動時点でこけてしまいます :cry: 
```
 ERROR  ENOENT: no such file or directory, open './certs/dev.pem'
```


チーム開発で「初回は`devServer`を消して実行してね」と共通認識をもってもらうのも手間だと感じたため、 公開鍵・秘密鍵があるかないかを`fs`の`existsSync`で判定する形に調整することで解決しました。
（但し、初回の`nuxi dev`はhttpになります）

```diff_typescript
+ import { existsSync } from 'fs'
import mkcert from 'vite-plugin-mkcert'

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  // 上と違いないので省略
-  devServer: {
-     https: {
-       cert: './certs/cert.pem',
-       key: './certs/dev.pem'
-    }
-  },
+  devServer: existsSync('./certs/cert.pem') && existsSync('./certs/dev.pem')
+  ? {
+    https: {
+      cert: './certs/cert.pem',
+      key: './certs/dev.pem',
+    },
+  }
+  : undefined,
});
  
```

## :penguin: WSL2で開発してる場合
WSL2で開発している場合も同様によしなにやってくれますが、恐らく開発ではWSL2を使っていてもブラウザはWindows上で動かしていることがほとんどかと思います。
その場合、認証局のインストールはWindows側でする必要があります。

1. 
    WSL側でvite-plugin-mkcertが生成してくれた鍵をopensslコマンドを用いてWindows側で利用できる形式に変換します。
    この際パスワードの設定が必要になります
    ```shell
    openssl pkcs12 -export -inkey rootCA-key.pem -in rootCA.pem -out rootCA.pfx
    ```
    <br>

2. Windowsの証明書管理ツール（certmgr.msc）を開きます。
    信頼されたルート証明機関 → 証明書を右クリック → インポート にてインポートウィザードで先ほど変換した rootCA.pfx をインポートします
    
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279880/970386f4-099e-3bad-ee12-70f57b3ebaaa.png)

    - 先ほど設定したパスワードの入力が必要になります
    - 証明書ストアの選択では「証明書をすべて次のストアに配置する → 信頼されたルート証明機関」を選択しています（デフォルトまま）

    インポートウィザードに従うがまま、正しくインポートされました :clap: 

    ![{83A47190-8856-40F2-A064-E7CF5FD55D52}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279880/fef11abb-2c7a-3d40-82f8-5e1128a57ccf.png)

    <details>
    <summary>補足（エクスプローラーからWSLのディレクトリを開く方法）</summary>
    <div>
    
    上のopensslコマンドで変換した場合、証明書をインポートの際にWindowsのエクスプローラーからWSLのディレクトリを該当ディレクトリ開く必要があると思いますが、`\\wsl$`から開くことができます。
    
    ![{E8116EC9-A003-4495-B646-AC903AEA5DD1}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279880/1f9c4d09-15c4-7a2d-2bd0-e4fb10b0aef0.png)
    </div>
    
    </details>
    <br>

3. ブラウザ側でページを確認して証明書が有効になっていれば完了です :confetti_ball:

    ![{DF7F423D-5F92-4B38-B8E7-F6A19BA31354}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279880/f7afc253-47aa-bd31-9616-49eefab2e451.png)

## まとめ

- 簡単にhttpsで接続することができました 🎉
- Secure属性つきのCookieの設定やhttpsを必須とするサードパーティのAPI通信のようなときに有用です

## 参考にさせていただいた記事
https://qiita.com/recordare/items/d51f50dc634187e20538
https://web.dev/articles/how-to-use-local-https?hl=ja

# 一緒に二次元業界を盛り上げていきませんか？
株式会社viviONでは、フロントエンドエンジニアを募集しています。

https://vivion.jp/recruit/

また、フロントエンドエンジニアに限らず、バックエンド・SRE・スマホアプリなど様々なエンジニア職を募集していますので、ぜひ採用情報をご覧ください。