﻿# 使用 Dev Tunnels (開發人員通道) 快速打造一個對外公開的測試連結

開發 [Webhook](https://en.wikipedia.org/wiki/Webhook) 應用程式的時候，最麻煩的地方就是如何讓外部的服務可以連線到你的本機開發環境。除此之外，要讓身邊的手機快速連到你正在開發中的網站，如果能快速建立一個對外公開的連結，且最好是 HTTPS 安全連線的網址，那也會十分方便。今天我要介紹一個微軟官方推出的 [Dev Tunnels](https://docs.microsoft.com/en-us/azure/developer/dev-tunnels/?WT.mc_id=DT-MVP-4015686) 服務，它擁有完整的**命令列工具**，同時也內建於 [Visual Studio Code](https://code.visualstudio.com/) 與 [Visual Studio 2022](https://visualstudio.microsoft.com/zh-hant/vs/) 之中，不但此服務完全免費，還十分容易上手，我們就馬上來看看怎樣使用吧！

![A wide banner image featuring a visual metaphor for Dev Tunnels service  A bright, modern tunnel of light and data representing a secure connection fr](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/1895bd8fd4fe4111e0ee-e67c5c53-30bc-4c2d-af81-d525464149f8.webp)

### Dev Tunnels 是什麼？

Dev Tunnels (**開發人員通道**) 允許開發人員安全地將**本機 Web 服務**公開到 Internet，還能控制誰有權訪問你的網站或 Web API，並從任何地方輕鬆偵錯您的 Web 應用程式。

這個服務跟 [ngrok](https://ngrok.com/) 或 [Cloudflare Tunnel](https://www.cloudflare.com/products/tunnel/) 其實是同樣性質的產品，都是透過一個中繼伺服器，讓你的本機開發環境可以透過一個對外公開的網址，讓 Internet 外部網路可以連線到你的本機開發環境。

使用 Dev Tunnels 服務的好處是，就是他跟微軟的開發工具整合的非常好，在 Visual Studio Code 與 Visual Studio 2022 都有內建這個功能，使用上真的非常方便，你根本不用特別使用**命令列工具**，就可以在本機開發環境快速建立一個對外公開的測試連結。

### 如何在 Visual Studio Code 使用 Dev Tunnels

在 VS Code 使用 Dev Tunnels 其實非常簡單，操作上也蠻直覺的，請參考以下步驟進行啟用：

1.  使用 Dev Tunnels 前先啟動本機開發伺服器
    
    我以 Angular 為例，輸入 `ng serve` 啟動開發伺服器，並且在瀏覽器中打開 [http://localhost:4200](http://localhost:4200) 確認伺服器已經正常運作。
    
    ![ng serve](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/15bf544ebea54f88af79-17d765c8-9aec-4219-a95f-3ab17d36a310.png)
    
2.  執行 `F1` > `Forward a port` 命令
    
    ![Forward a port](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/856ecfd9bd5f093a89b7-cac4c121-3bb7-4fba-8aae-9a40c221f971.png)
    
3.  選擇要轉發的 Port 號碼
    
    按下 **Forward a port** 按鈕
    
    ![image](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/d4c12294db752ced37a1-9b5419a0-6248-4daf-9569-9b12151f7296.png)
    
    輸入 Port 號碼 `4200`，按下 **Enter** 確認
    
    ![image](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/f12f5b8b12b14aa62f9e-73558848-7870-46ea-b564-545c020f9356.png)
    
    這樣就設定完成了！
    
    從下圖你可以看到，你已經建立了一個對外公開的網址，並且可以透過 HTTPS 安全連線的方式連線到你的本機開發環境。按下 Preview in Editor 就可以直接在 Visual Studio Code 中用此網址開啟網站。
    
    ![image](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/361505a7499d2f50f9fb-b87515b3-caff-44cf-8a8a-d57ba12f6d47.png)
    

如果只是個人要開發測試之用，其實這樣就夠了。但有點要特別注意的地方，就是它有個 `Visibility` (可視性) 欄位，可以讓你控制這個 **Forwarded Address** 對外網址的瀏覽權限：

1.  `Private` (私人連線) \[預設值\]
    
    只有你自己可以連線到這個 **Forwarded Address** 網址！
    
    你可以嘗試開一個「無痕視窗」連到該網址看看，他會要求你登入 GitHub 帳號才能打開這個網址。因此預設在使用上非常安全，其他人無法任意連線到你的本機開發環境。
    
    ![Sign in to GitHub to continue to Dev Tunnels](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/9590d9a6cd2e5dfb129f-ceeeca71-7282-494f-b935-46b51a75618f.png)
    
2.  `Public` (公開連線)
    
    如果你想開發的是 Webhook 類型的應用，就比較無法要求對方伺服器要登入才能存取你的 API，這時你就可以把 Visibility (可視性) 設定為 Public (公開連線)，這樣就可以讓任何人都可以連線到你的本機開發環境。
    
    ![Port Visibility](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/e3a1d3e251451bbc88d9-6bb4cd2a-1588-437f-954b-57f895afe717.png)
    

還有一點要注意，這個 [Dev Tunnels](https://docs.microsoft.com/en-us/azure/developer/dev-tunnels/?WT.mc_id=DT-MVP-4015686) 服務預設會在你的電腦與該服務之間建立好一個 VPN 通道，然後將網路封包轉送到你的電腦，使用者連接 Dev Tunnels 提供的網址時，是使用 HTTPS 加密連線的，但從 Local Proxy 連到你的本機服務時，預設是走 `HTTP` 非加密連線，這個過程我們稱為 [TLS termination](https://en.wikipedia.org/wiki/TLS_termination_proxy) 或 **SSL offloading**。

如果你的本機使用的是 HTTPS 加密連線，目前 Visual Studio Code 內建的功能是無法順利切換成 HTTPS 連線的，你必須使用**命令列工具**才能順利建立使用 HTTPS 後端服務的連線。我認為這是個 Bug 並已回報到 [Unable switch to HTTPS for Local Port Forwarding #201465](https://github.com/microsoft/vscode/issues/201465) 這裡。

![Change Port Protocol](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/76070bb8f54d8dfe3a7b-2b5e1d6f-1f2c-4496-8aa0-dab82ffb0d59.png)

目前 Visual Studio Code 的功能就這麼簡單，但已經可以應付 90% 的應用場景，如果你想要更多的功能，就必須使用**命令列工具**了。

### 如何在 Visual Studio 2022 使用 Dev Tunnels

Visual Studio 2022 內建的 Dev Tunnels 功能比 Visual Studio Code 更強大，功能更多，使用上不能算太難，但跟 Visual Studio Code 比起來使用習慣上不太一樣。

1.  首先，先建立一個**開發人員通道**
    
    ![開發人員通道](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/8c3adc18ab65fae931cf-b0acca39-3eb4-4fc8-b262-97cb3a5ea00c.png)
    
    ![建立一個開發人員通道](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/d07e61c4021953cbd961-57dbddd0-2c45-4ef3-8e97-2a5e35c89a35.png)
    
2.  建立好之後，就跟往常一樣直接按下 `F5` 或 `Ctrl+F5` 開啟測試網站，預設就會開啟 Dev Tunnels 轉發的網址了！
    
    第一次開啟會顯示如下圖畫面，按下 **Continue** 就能夠繼續！
    
    ![image](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/81a85f36758edb92949f-d035255f-1548-451f-b331-0f2cd3df6b37.png)
    
    如果你的 HTTP Request 的 `Accept` 標頭設定為 `*/*` 或 `application/json` 的話，預設也不會顯示這個畫面！
    
    > 它背後其實是寫入兩個 Cookies，只要 HTTP 要求有這兩個 Cookies 就不會再次提示這個畫面。
    
3.  顯示開發人員通道視窗
    
    由於 Visual Studio 2022 對於 Dev Tunnels 的支援功能比較多，所以有蠻多東西可以看的，你要先顯示開發人員通道視窗，才能看到更多功能。
    
    ![顯示開發人員通道視窗](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/0f2d3d8d90766d5aa5c0-5ee47946-c6ca-45a8-b197-66c560e28cb8.png)
    
    你可以點擊「通道 URL」欄位的「檢視」就可以打開瀏覽器，但這個往只要在你按下 `F5` 或 `Ctrl+F5` 開啟測試網站後才會出現！
    
    ![開發人員通道](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/227c2588593462e8219b-dbf5ea39-1fe9-45c5-a6e2-19356af53aa7.png)
    
    由於 Dev Tunnels 是一項免費服務，為了避免服務被濫用，所以有每月使用量的上限，超過就不能用了，你透過點擊「顯示開發人員通道使用方式限制」查看剩餘的用量剩下多少。
    
    ![顯示開發人員通道使用方式限制](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/30e5ccc1a4244409e340-6d605551-9d17-4c14-9741-1a29f2239ddd.png)
    
    如果真的只是自己測試用的話，一個月 2.0 GB 的頻寬用量其實已經很多了，真的不夠的話，換個帳戶建立開發人員通道即可，每個帳戶都是分開計算的。
    
    ![開發人員通道使用方式限制](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/847a3f66becb4627769b-9d45789f-c377-41d9-a72b-da2d29f56f8d.png)
    

### 如何在命令列工具使用 Dev Tunnels

我認為 [Dev Tunnels](https://docs.microsoft.com/en-us/azure/developer/dev-tunnels/?WT.mc_id=DT-MVP-4015686) 服務提供的功能真的很多，你在 Visual Studio Code 或 Visual Studio 2022 都沒辦法真正感受到他的強大，如果你想要更多的功能，就必須使用**命令列工具**了。

先來看看怎麼安裝：

-   Windows
    
    ```bash
    winget install Microsoft.devtunnel
    ```
    
-   macOS
    
    ```bash
    brew install --cask devtunnel
    ```
    
-   Linux
    
    ```bash
    curl -sL https://aka.ms/DevTunnelCliInstall | bash
    ```
    

再來看怎麼使用：

1.  第一次使用要先登入
    
    登入 Microsoft Entra ID 或 Microsoft 帳戶
    
    ```bash
    devtunnel user login
    ```
    
    登入 GitHub 帳號要加上 `-g` 參數：
    
    ```bash
    devtunnel user login -g
    ```
    
    > 若要使用 Device Code 登入，請加上 `-d` 參數。
    
    顯示目前登入的帳號：
    
    ```bash
    devtunnel user show
    ```
    
    登出目前帳號：
    
    ```bash
    devtunnel user logout
    ```
    
2.  建立開發人員通道
    
    快速建立一個 Port 4200 的開發人員通道：
    
    ```bash
    devtunnel host -p 4200
    ```
    
    你也可以一次建立多個 Port 的開發人員通道：
    
    ```bash
    devtunnel host -p 3000 4200
    ```
    
    快速建立一個 Port 4200 的開發人員通道，網址需可以匿名連線 (公開網址)：
    
    ```bash
    devtunnel host -p 4200 --allow-anonymous
    ```
    
    不要使用 TLS Termination，後端服務採用 HTTPS 加密連線：
    
    ```bash
    devtunnel host -p 8443 --protocol https
    ```
    
    設定開發人員通道會在 2 天後自動到期 (時間到自動斷線)：
    
    ```bash
    devtunnel host -p 4200 --expiration 2d
    ```
    

使用命令列工具來建立開發人員通道，你可以看到的資訊比較多，我以這個命令為例：

```bash
devtunnel host -p 4200 --expiration 2d -a
```

你會得到以下訊息：

```
Hosting port: 4200
Connect via browser: https://1blj4ljk.asse.devtunnels.ms:4200, https://1blj4ljk-4200.asse.devtunnels.ms
Inspect network activity: https://1blj4ljk-4200-inspect.asse.devtunnels.ms

Ready to accept connections for tunnel: joyful-mountain-55r3k63
```

這裡有 3 個連結，第一行 `Connect via browser` 提供的連結就是可以讓你從外網連線到你本機的網址。

另一個 `Inspect network activity` 就真的很酷了，他可以幫助你看到所有經過 Dev Tunnels 的網路封包，這個功能在偵錯 Webhook 應用程式時非常有用，你可以看到所有經過 Dev Tunnels 的 HTTP Request 與 HTTP Response，超級實用！

請注意下圖，我可不是按下 F12 開啟開發人員工具喔，而是開啟 `Inspect network activity` 的網址，連上來之後，任何人透過 `Connect via browser` 連進來的所有封包，全部都會一五一十的呈現在這裡，偵錯超方便！👍

![Inspect network activity - DevTools](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/195249153d1f9b9bd7e8-47f77f1a-7b30-4ef7-8c9b-43f70e3b116b.png)

### 如何建立一個長久通道

上面的例子都是建立 Dev Tunnels 的「臨時通道」而已，每次建立時的網址都會變，真的只適合臨時測試之用。Dev Tunnels 其實可以建立「長久通道」，如此一來你就可以固定下測試的網址，並且可以長久使用。以下是建立方式的示範：

1.  建立一個長久通道
    
    建立一個開發人員通道：
    
    ```bash
    devtunnel create
    ```
    
    你會得到以下訊息：
    
    ```
    Welcome to dev tunnels!
    CLI version: 1.0.1042+788c4fbe73
    
    By using the software, you agree to
      - the dev tunnels License Terms: https://aka.ms/devtunnels/tos
      - the Microsoft Privacy Statement: https://privacy.microsoft.com/privacystatement
    
    Report issues on GitHub: https://aka.ms/devtunnels/issues
    Use 'devtunnel --help' to see available commands or visit: https://aka.ms/devtunnels/docs
    
    Tunnel ID             : quick-dog-nwk0lqp.asse
    Name                  :
    Description           :
    Labels                :
    Access control        : {}
    Host connections      : 0
    Client connections    : 0
    Current upload rate   : 0 MB/s (limit: 20 MB/s)
    Current download rate : 0 MB/s (limit: 20 MB/s)
    Tunnel Expiration     : 30 days
    
    Set default tunnel to quick-dog-nwk0lqp.
    ```
    
    > 這裡的 `quick-dog-nwk0lqp` 代表你的長久通道 ID，你可以透過 `devtunnel list` 查詢你的長久通道 ID。
    
2.  替既有的長久通道建立 Port 對應
    
    ```bash
    devtunnel port create -p 4200 --protocol http
    ```
    
3.  啟動 Dev Tunnels 開發人員通道
    
    ```bash
    devtunnel host
    ```
    

其實 Dev Tunnels 的命令列工具還有很多功能，如果你想瞭解更多功能，可以參考[官方文件](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/cli-commands?WT.mc_id=DT-MVP-4015686#advanced-manage-dev-tunnel-access)說明。

### 注意 Host 標頭的特性

由於 Dev Tunnels 是透過一個中繼伺服器，將網路封包轉送到你的電腦，所以你的本機開發環境會看到的 HTTP Request 的 `Host` 標頭，預設會是 `localhost:PORT` 為主。這是因為 Dev Tunnels 的設計本意就是幫助你將本機的開發伺服器對外提供測試之用。

但是，如果你的本機服務必須要指定 IP 或網址才能連線的話，就必須要透過 `--host-header` 參數來指定 `Host` 標頭的值，例如：

這裡的 `--host-header` 參數可以設定以下兩種值：

1.  `unchanged`
    
    預設會使用 Dev Tunnels 傳入的 Hostname 為主：
    
    ```bash
    devtunnel host -p 5052 --host-header "unchanged"
    ```
    
2.  `自訂任意 IP 或域名`
    
    ```bash
    devtunnel host -p 5052 --host-header "192.168.100.37"
    ```
    

> 注意: 以上述範例來說，如果你沒有設定 `--host-header` 參數時，預設你的本機服務會看到的 `Host` 標頭是 `localhost:5052`。

### 相關連結

-   官方文件
    -   [Dev Tunnels documentation](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/?WT.mc_id=DT-MVP-4015686)
    -   [Create and host a dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows&WT.mc_id=DT-MVP-4015686)
    -   [Dev Tunnels limits](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/azure-subscription-service-limits?WT.mc_id=DT-MVP-4015686#dev-tunnels-limits)
-   GitHub
    -   [Issues](https://github.com/Microsoft/dev-tunnels/issues)
-   Visual Studio Code
    -   [Port forwarding local services with VS Code](https://code.visualstudio.com/docs/editor/port-forwarding)
-   Visual Studio 2022
    -   [Dev Tunnels in Visual Studio 2022 | Microsoft Learn](https://learn.microsoft.com/en-us/aspnet/core/test/dev-tunnels?view=aspnetcore-8.0&WT.mc_id=DT-MVP-4015686)
-   CLI
    -   [Dev Tunnels command-line reference - Microsoft dev Tunnels | Microsoft Learn](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/cli-commands?WT.mc_id=DT-MVP-4015686)
