網頁

Wednesday, November 21, 2018

[C#] Swashbuckle WebAPI HTTPS BaseUrl and Bearer token

因為Swashbuckle作者跑去專心做Swashbuckle.AspNetCore了,所以在使用上遇到一些問題時要自己想辦法解,這邊紀錄一下遇到的兩個問題。


HTTPS BaseUrl Issue

因為我有用 cloudflare 的 Flexible SSL,在production環境上外面看起來是HTTPS,但Server上走的仍然是HTTP,這時候swagger的 BaseUrl 會因為 Uri Scheme 出問題,所以要來想辦法解,整理需求後,我只需要本機測試(localhost)走HTTP,其他就走HTTPS,按照這個需求來做的解法如下。

//SwaggerConfig.cs
config.EnableSwagger(c =>
{
    c.RootUrl(ResolveBasePath);
    c.Schemes(new[] { "http", "https" });
}

internal static string ResolveBasePath(HttpRequestMessage message)
{
    //fix for Cloudflare Flexible SSL and localhost test
    var scheme = message.RequestUri.Host.IndexOf("localhost") > -1 ? "http://" : "https://";
    return scheme + message.RequestUri.Authority;
}

這樣就可以兼顧正式機與本機開發都正常使用,如果透過proxy那要再另外解,我這邊就先略過。



Bearer token Issue

Swagger可以支援Authorization Bearer Token沒問題,但是Swashbuckle的Swagger UI上有點bug,要修正後才能正常運作,這邊解法主要是參考stackoverflow,不過因為是蠻久之前找的,現在找不到哪一篇看到的,沒辦法附上來源。

//SwaggerConfig.cs
config.EnableSwagger(c =>
{
    c.ApiKey("Token")
    .Description("The Bearer authentication scheme was originally created as part of OAuth 2.0 in RFC 6750")
    .Name("Authorization")
    .In("header");
})
.EnableSwaggerUi(c =>
{
    c.InjectJavaScript(thisAssembly, "[YOUR NAMESPACE].SwaggerJs.SwaggerUiCustomization.js");
    c.EnableApiKeySupport("Authorization", "header");
});
上面的namespace記得改。

SwaggerConfig設定完後,還要加個js檔來處理swagger前端頁面送出api_key的編碼問題,在WebAPI專案下新增一個資料夾,裡面新增一個JS檔,名稱要跟上面的config對應,像我這樣寫的話就是新增一個叫做SwaggerJs的資料夾,然後放進SwaggerUiCustomization.js這個檔案。

//SwaggerUiCustomization.js
(function () {
    function addApiKeyAuthorization() {
        var key = $('#input_apiKey')[0].value;
        if (key && key.trim() != "") {
            var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization(swashbuckleConfig.apiKeyName, key, swashbuckleConfig.apiKeyIn);
            window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth);
            log("added key " + key);
        }
    }
    $('#input_apiKey').change(addApiKeyAuthorization);
})();

大概就是這樣。

No comments:

Post a Comment