Home >> Blog >> 如何在 Windows 和 Visual Studio 中使用 ngrok 來測試 webhook

如何在 Windows 和 Visual Studio 中使用 ngrok 來測試 webhook

讓我們看

ngrok 快速通道:Visual Studio 的 ngrok 擴展

開始使用 ngrok 和 Visual Studio 的最快方法是使用 Visual Studio 的開源擴展,它將為當前開放解決方案中的任何 Web 應用程式啟動 ngrok。它將為您找出端口並為您的應用程式啟動必要的隧道。

如何在 Windows 和 Visual Studio 中使用 ngrok 來測試 webhook

從 Visual Studio“工具”菜單中選擇“啟動 ngrok Tunnel”,ngrok 將啟動,您將看到應用程式的新公共 URL。

如何在 Windows 和 Visual Studio 中使用 ngrok 來測試 webhook

在這裡,ngrok 給了我們https://a9f03915.ngrok.io的 URL 。確保您已在 Visual Studio 中啟動應用程式,然後嘗試在瀏覽器中打開該 URL。它應該從您的本地開發機器加載應用程式。現在,您有了一個可以提供給任何人或在 webhook 配置中使用的 URL(例如在Twilio 控制台中),它將訪問您電腦上運行的應用程式。您可以在程式碼中設置斷點,並在本地運行應用程式時執行幾乎所有您習慣的操作。

您可以在開發SEO優化應用程式時讓 ngrok 繼續運行。如果您停止應用程式,ngrok 可以繼續運行,並在您重新啟動應用程式時恢復為您的應用程式提供流量。如果您確實關閉了 ngrok,那麼當它重新啟動時,您將獲得一個新的URL。這意味著如果您已使用 ngrok URL 配置了 webhook,則每次重新啟動 ngrok 時都需要更新它。

在 Windows 上安裝 ngrok

當您使用Visual Studio 擴展時,它會自動為您下載並安裝 ngrok。但是,如果您不使用 Visual Studio,則需要自己安裝 ngrok。

使用 Chocolatey 包管理器

如果您使用Chocolatey 包管理器(強烈推薦),安裝只需要從提升的命令提示符處執行以下命令:

choco install ngrok.portable

這將在您的 PATH 中安裝 ngrok,以便您可以從任何目錄運行它。

手動安裝

手動安裝 ngrok 涉及更多步驟:

  1. 下載 ngrok ZIP 文件
  2. 解壓 ngrok.exe 文件
  3. 將 ngrok.exe 放在您選擇的文件夾中
  4. 確保該文件夾在您的PATH 環境變量中

測試您的安裝

要測試 ngrok 是否安裝正確,請打開一個新的命令窗口(命令提示符或 PowerShell)並運行以下命令:

ngrok version

它應該打印一個類似“ngrok version 2.xx”的字符串。如果你得到類似“'ngrok' 無法識別”的訊息,這可能意味著你的 PATH 環境變量中沒有包含 ngrok.exe 的文件夾。您可能還需要打開一個新的命令窗口。

安裝 ngrok 後,就可以在 Visual Studio 項目中使用它了。

在 Visual Studio 託管的 ASP.NET 應用程式中手動使用 ngrok

從命令行啟動 ngrok

當您使用 Visual Studio 託管 ASP.NET 應用程式時,它通常使用 IIS Express,但可能會使用其他 Web 伺服器軟件,具體取決於您使用的 Visual Studio 版本以及您如何配置應用程式。無論設置如何,您都需要運行一個簡單的命令來為您的應用程式創建一個新的公共隧道:

ngrok http -host-header="localhost:[port]" [port]

要了解您的應用在哪個端口上運行,請從 Visual Studio 運行該應用。它將使用您的新應用啟動 Web 瀏覽器,您將在地址欄中看到 URL:

如何在 Windows 和 Visual Studio 中使用 ngrok 來測試 webhook

在此示例中,端口號為 58821,但您會發現 Visual Studio 為您創建的每個新 ASP.NET 項目分配了一個隨機端口號。值得慶幸的是,對於您正在從事的特定項目,它保持不變。

對於這個例子,ngrok 命令將是:

ngrok http -host-header="localhost:58821" 58821

ngrok 將啟動,您將看到應用的新公共 URL。

如何在 Windows 和 Visual Studio 中使用 ngrok 來測試 webhook

在這裡,ngrok 給了我們https://a9f03915.ngrok.io的 URL 。確保您已在 Visual Studio 中啟動應用程式,然後嘗試在瀏覽器中打開該 URL。它應該從您的本地開發機器加載應用程式。現在,您有了一個可以提供給任何人或在 webhook 配置中使用的 URL(例如在Twilio 控制台中),它將訪問您電腦上運行的應用程式。您可以在程式碼中設置斷點,並在本地運行應用程式時執行幾乎所有您習慣的操作。

您可以在開發應用程式時讓 ngrok 繼續運行。如果您停止應用程式,ngrok 可以繼續運行,並在您重新啟動應用程式時恢復為您的應用程式提供流量。如果您確實關閉了 ngrok,那麼當它重新啟動時,您將獲得一個新的URL。這意味著如果您已使用 ngrok URL 配置了 webhook,則每次重新啟動 ngrok 時都需要更新它。

每次使用相同的 ngrok 域

ngrok 提供付費計劃,可讓您使用自定義域,例如“my-cool-app.ngrok.io”。每次啟動 ngrok 時都可以使用域,因此無需更新 webhook 配置。當您獲得付費計劃時,您將獲得一個需要安裝的 authtoken 。您只需要運行一次命令:

ngrok authtoken [yourtoken]

然後,保留您的域名並將-subdomain參數添加到命令行:

Tngrok http -host-header="localhost:58821" -subdomain my-cool-app 58821

現在,您可以始終使用https://my-cool-app.ngrok.io來訪問您的開發環境。

如果您使用的是Visual Studio 擴展,請在web.config文件的appSettings部分指定您希望它使用的子域,如下所示:

故障排除

有時事情可能會出錯,當你似乎無法讓你的 ngrok 隧道工作時,這裡有一些事情可以嘗試或考慮:

  1. 你的應用程式正在運行嗎?不僅隧道需要運行,而且您的應用程式也需要運行以響應請求。
  2. 您是否使用正確的端口號啟動 ngrok?確保 ngrok 將流量轉發到的端口與您的應用程式正在偵聽的端口匹配。
  3. 您是否嘗試過手動運行 ngrok?如果您正在使用 Visual Studio 擴展並且遇到問題,請嘗試按照本指南中的說明從命令行手動運行 ngrok。如果您可以讓它以這種方式工作,請提交該反饋,以便我們改進 Visual Studio 擴展。
  4. 確保您的項目配置為不使用 SSL。ngrok 無法通過隧道連接到啟用 SSL 的主機。在 Visual Studio 中,確保在“應用程式屬性”的“調試”選項卡中關閉“啟用 SSL”選項。
  5. 您的電腦是公司管理的電腦嗎?在某些情況下,您公司 IT 部門管理的電腦可能會被鎖定,以防止外部隧道軟件正常工作。如果是這種情況,您可以要求例外,或者您可能需要使用像Microsoft Azure這樣的公共 Web 主機來公開託管您的應用程式。

高級 ngrok 提示和技巧

獲取 ngrok 主機名

也許您有一些 C# 程式碼查看Request對像以嘗試找出要在絕對 URL 中使用的主機名。您可能正在做某事將完全限定的 URL 插入到電子郵件中,或者您可能正在使用Twilio API提供帶有 webhook URL 的電話號碼來接聽電話(這是一個好主意,拍拍自己的後背想那)。

不管是什麼原因,通常在 ASP.NET 中你想要主機名的時候,你在當前請求上使用Url.Host :

var myHostName = Request.Url.Host;

您可能會將其與Url.Port結合使用,以確保您在正確的端口上,因為您的本地開發環境不在默認端口上:

var myHostNameWithPort = Request.Url.Host + ":" + Request.Url.Port;

所以,如果你打開“http://localhost:1234/Home”,你會得到“localhost:1234”。如果您通過 ngrok 運行您的應用程式怎麼辦?也許出乎意料的是,即使您使用諸如“https://foo123.ngrok.io/Home”之類的 ngrok URL 訪問該頁面,上述程式碼仍將返回“localhost:1234”。這是因為為了讓 Visual Studio(和後台的 IIS Express Web 伺服器)允許請求進入您的本地環境,我們必須指示 ngrok 重寫主機頭。值得慶幸的是,有一個簡單的方法可以解決這個問題,因為 ngrok 將向我們傳遞一個我們可以使用的X-Original-Host標頭。

這是一個 C# 函數,如果X-Original-Host存在,它將使用它,否則它將像以前一樣使用 Url 屬性:

public static string GetDomainAndPort(HttpRequestBase request)
{
if (request.Headers["X-Original-Host"] != null)
{
// Assume default port for protocol (http=80, https=443)
return request.Headers["X-Original-Host"];
}

// Leave off port if it's the default 80/443
if (request.Url.Port == 80 || request.Url.Port == 443)
{
return request.Url.Host;
}
return request.Url.Host + ":" + request.Url.Port;
}

獲取 SSL 狀態

如果您正在構建一個完整的 URL,您可能想知道是否應該在其前面加上“http”或“https”。ngrok 兩者都支持,所以你可以默認使用 https 並且是安全的。如果你想知道用戶實際使用的協議,那麼你可以檢查X-Forwarded-Proto標頭:

public static string GetProtocol(HttpRequestBase request)
{
if (request.Headers["X-Forwarded-Proto"] != null)
{
return request.Headers["X-Forwarded-Proto"];
}

return request.IsSecureConnection ? "https" : "http";
}

X-Forwarded-Proto是前端代理伺服器的一個相當常見的標頭,因此無論您是在開發中使用 ngrok 運行還是在生產中使用AWS Elastic Load Balancer運行,程式碼都是可重用的。

獲取客戶端 IP 地址

由 ngrok 等代理傳遞的另一個常見標頭是X-Forwarded-For。此標頭用於提供發出 HTTP 請求的客戶端的原始 IP 地址。如果您只使用當前請求對象的典型UserHostAddress屬性,那麼您將始終獲得代理伺服器的 IP 地址(在我們的例子中,是 ngrok 的伺服器之一)。以下是檢測客戶端 IP 地址的正確方法,無論是否有代理:

public static string GetIpAddress(HttpRequestBase request)

{
return request.Headers["X-Forwarded-For"]
?? request.UserHostAddress;
}

將這三個函數放在一起,這是一個如何從控制器調用它們的示例:

public class TestController : Controller
{
// GET: Test
public ActionResult Index()
{
var html = "< html >< body >< pre >\n" +
"Your Protocol: " + ProxyHelper.GetProtocol(Request) + "\n" +
"Your Domain:Port: " + ProxyHelper.GetDomainAndPort(Request) + "\n" +
"Your IP Address: " + ProxyHelper.GetIpAddress(Request) + "\n" +
"";
return Content(html);
}
}