WSL(Ubuntu)上に立ち上げたフロントエンドとバックエンドの通信を可能にした時にやったこと

こんにちは！
[アイスタイル Advent Calender 2022](https://qiita.com/advent-calendar/2022/istyle)の4日目の記事を担当するkudomaです。

去年のアドカレは、TypeScriptで勇者になろうとした話について執筆しました。

https://techblog.istyle.co.jp/archives/8568

現在はWEB SREグループに所属し、[@cosme](https://www.cosme.net/)を他の言語でリプレイスしています。
フロントエンドもバックエンドもローカルで開発を行っています。

ローカル愛好家の僕は、最近今までとは違った環境構築を行いました。
今回はその時にやったことを紹介します。

# 経緯
今までは1アプリケーションをターゲットに環境構築する機会しかありませんでした。
バックエンドならレスポンスをクライアントに返せたらOK。
フロントエンドならAPIへリクエストしたり、ブラウザ上に画面を表示したりできたらOK。
とそれぞれ個別に開発をしていました。

それが当時は、フロントエンドとバックエンドの両方に改修を入れる必要がある不具合を見つけたため、以下のような方法で動作確認しようと思いました。
- バックエンドを先に修正し、共有のリモートサーバーへデプロイ
- フロントエンドはローカルで修正し、動作確認

しかしこういう時に限り、共有のリモートサーバーは別案件で利用されていて使うことができませんでした。
なので、両方ともローカルで立ち上げて、動作確認してみることにしました。

# 作成した環境について
以下が構成図です。
フロントエンドとバックエンドはUbuntu上で立ち上がっていて、フロントエンドへのアクセスはブラウザから行います。
![hogehoge (5).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/738621/d3af8473-460b-d207-44c4-f56f907b09c8.jpeg)

# 前提
### 説明に関係するツール情報
- OS / Windows10 + WSL2 + Ubuntu
- ブラウザ / Google Chrome
- フロントエンド / Nuxt.js
- バックエンド / Express.js + TypeScript

### システムの概要
- フロントエンド
  - バックエンド(API)からデータを取得して表示する
  - ログインは別ドメインで稼働しているページで行う
- バックエンド
  - フロントで表示したいデータを返す
  - ユーザ情報はクライアント(フロントエンド)から渡されたCookieを元に取得する
- ログイン機能を持ったページ
  - 今回フロントエンドと呼んでいるサイトとは別ドメインで稼働しているページ

# 何もいじってない状態でフロントにアクセスしてみたら
- フロントエンドを表示してみると、バックエンドの不具合修正が反映されていなかった
⇒ フロントエンドからリモートサーバーのバックエンドへリクエストしているから(と推測)

- ログインしているはずなのに、未ログイン状態の画面が表示された
⇒ Cookieを使えていないと思われる
⇒ Cookieを発行するログイン機能の開発環境とCookieを使用するフロントエンドの開発環境でドメインが違うから(と推測)

![hogehoge (7).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/738621/30111e7b-7141-de88-ca26-66cede76dd47.jpeg)

# 方針
- フロントエンドはローカルのバックエンドへリクエストを送るようにする
- 修正対象がログイン状態で使うページのため、Cookieも使用できるようにする

# 実践

## フロントエンドからローカルのバックエンドへリクエストを送るようにする
自力で接続先を個別に設定することができなかったので、今回は以下のような修正をします。
- フロントエンドが向いているAPIサーバーのFQDNを、リモートサーバーのIPではなくローカルのIPを指すようにする
- APIサーバーのポートは443なので、ローカルも443で立ち上げる

### Ubuntuでは名前解決をどのように行うか
Ubuntuでは`/etc/nsswitch.conf`を見れば、どういう順番で名前解決をしているか確認できるらしいです。

僕の出力は以下の通りです。
```
# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc-reference' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.

passwd:         files systemd
group:          files systemd
shadow:         files
gshadow:        files

hosts:          files dns
networks:       files

protocols:      db files
services:       db files
ethers:         db files
rpc:            db files

netgroup:       nis
```

この出力のhostsを見ると、左からfiles、dnsと記載があると思うのですが、これはFQDNの名前解決をしていく順番です。
最初に`/etc/hosts`を見に行って、そこで名前解決できなかったら、DNSサーバーを見に行くということです。

すげぇwww
なんかテンションあがる ↗↗↗

### UbuntuでFQDNとローカルIPの対応付けをする
`/etc/hosts`に以下を追記します。
```
172.XX.XXX.XXX api.hoge.fuga
```

Ubuntuの名前解決に関する対応は以上です！

### バックエンドを443ポートで立ち上げる
ここの章はワイの独り言を添えます。

一瞬でしょ！ポート書き換えて`npm run dev`！
へ？なんか権限エラー出た。
```
Port 443 requires elevated privileges
```

ハイハイ任せてくれ、sudo付けてEnter!
へ？npmが使えん？

そしてこの方の記事に辿り着きました。

https://tech-drive.net/pc/2018062701/

上記の記事を参考にrootユーザを作成して、nodeなど実行に必要なツールをインストールします。
そして、rootユーザで`npm run dev`！

きたぁ～！！！バックエンドを443で立ち上げられました！ヒャッホ～！

### フロントエンドがローカルのバックエンドへリクエストを送れているか確認
ここの章はワイと先輩の会話を添えます。

ワイ「一旦、Ubuntu上で `curl -k "https://api.hoge.fuga/"` 叩いて確認しま～す」
ワイ「バックエンドの修正内容が反映されてやがる！嬉しすぎるw」

ワイ「次は実際にブラウザからフロントエンドへアクセスして、フロントエンドがローカルのバックエンドへリクエストを送れているか確認しよう」

ワイ「ブラウザの検索バーにURLを入力してEnter!」
ワイ「ハイハイ、バックエンドの修正内容確認できるんでしょw」

ワイ「へ？なんで反映されてない？何が間違ってた？え？」
ワイ「なんでリモートサーバーを見に行ってるねん、もうわからん」
ワイ「先輩お助けてください...」

先輩「アプリケーション側でDNSキャッシュが効いてるので、一旦削除してみるとか？」

ワイ「ほほぉ...まじかDNSキャッシュってのが存在するの？」
ワイ「うわぁ、まじで存在してるやんw」
ワイ「DNSサーバーに何度も問い合わせんの通信の無駄だから、キャッシュして時間を節約できるっていうメリットがあるのか」

https://www.npmjs.com/package/cacheable-lookup

ワイ「cacheable-lookupにはclearメソッドあるらしいので、アプリケーションで呼ぶように削除しよう！」
ワイ「よし、できた」

ワイ「再度フロントにアクセスしてみるぞぉ～」
ワイ「ハイ、`500 RuntimeError`が出ました。」
ワイ「バタンキュー。先輩うまくいかねっす...」

先輩「DEV用の証明書使ってるからでは？」

ワイ「たったしかに...」
ワイ「DEVのFQDNは`api.dev-hoge.fuga`だから、FQDN変わったことで証明書の警告が出てるのか...」

### axiosの証明書エラーの警告を無視する
ここからは平常運転に戻ります。

以下のaxiosのissueを参考にしました。

https://github.com/axios/axios/issues/535

フロントにアクセスしてみると...バックエンドの修正内容が反映されているのが確認できました！！！
ここまでで、ローカルに立ち上げたフロントエンドとバックエンド間で通信できるようになりました。

今こんな感じです。
![hogehoge (8).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/738621/2999fda8-6acc-00a5-eec9-799faa3667cc.jpeg)

## Cookieを使用できるようにする
後は、ブラウザで`https://front.hoge.huga:3000`を検索した際に、ローカルのフロントエンドへアクセスできるようにしたら完璧です。

### Windowsでは名前解決をどのように行うか

以下の記事を見て、DNSサーバーより先にローカルのhostsファイルを優先することがわかりました。

https://support.microsoft.com/ja-jp/topic/microsoft-tcp-ip-%E3%81%AE%E3%83%9B%E3%82%B9%E3%83%88%E5%90%8D%E8%A7%A3%E6%B1%BA%E3%81%AE%E9%A0%86%E5%BA%8F-dae00cc9-7e9c-c0cc-8360-477b99cb978a

### WindowsでFQDNとローカルIPの対応付けをする
`/c/Windows/System32/drivers/etc/hosts`に以下を追記します。
```
127.0.0.1 front.hoge.fuga
```

ただ、ここも結構めんどかったのですが、権限があって上書きできませんでした。
以下の記事を参考にメモ帳+管理者権限でhostsファイルを開いて、上書きしました。

https://onoredekaiketsu.com/howto-change-hosts-file-of-windows10/#toc3

ブラウザで`https://front.hoge.huga:3000`を検索してみます。
問題なくローカルのフロントエンドにアクセスでき、Cookieも使用することができました。

# 最後に
最後まで見て頂きありがとうございます。
僕としては知識の整理ができたので楽しかったですw

レビューを受けたら、改善できる可能性が出てきたので、さらに検証を重ねようと思います！

ここまで見て頂いた方々に何かを与えることができた記事だったら幸いです。
25日まで毎日アドカレの記事が[アイスタイル Advent Calender 2022](https://qiita.com/advent-calendar/2022/istyle)に載っていくと思いますので、お楽しみに！

# 参考文献
- [[Ubuntu]rootでログインできるようにする | TechDrive](https://tech-drive.net/pc/2018062701/)
- [cacheable-lookup | npm](https://www.npmjs.com/package/cacheable-lookup)
- [How to ignore SSL issues | Github](https://github.com/axios/axios/issues/535)
- [Microsoft TCP/IP のホスト名解決の順序 | Microsoft サポート](https://support.microsoft.com/ja-jp/topic/microsoft-tcp-ip-%E3%81%AE%E3%83%9B%E3%82%B9%E3%83%88%E5%90%8D%E8%A7%A3%E6%B1%BA%E3%81%AE%E9%A0%86%E5%BA%8F-dae00cc9-7e9c-c0cc-8360-477b99cb978a)
- [Windows10のhostsファイル変更方法【localでの開発環境など】 | 己で解決！泣かぬなら己で鳴こうホトトギス](https://onoredekaiketsu.com/howto-change-hosts-file-of-windows10/#toc3)