引言

  在 上一篇 中提到了 Swagger 的基本使用,僅限於沒有引數,沒有驗證的那種api文件生成,那麼這篇就連線上篇繼續,在一般具有安全性、許可權等驗證的介面上,

  都會在header/url中加上請求者的祕鑰、簽名等,當然也有可能新增到body等其它地方, Swashbuckle.AspNetCore 都支援這些寫法。

  如何使用 -- 下面將介紹兩種使用方式

兩種方式引數設定到何處都是在  In屬性上,屬性對於值如下:    參考 https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#parameter-object

  • query: 引數欄位值對應放在url中
  • header: 引數值對應放在header param中
  • body: 引數對應放到請求體中
  • path: 引數應該對應放到請求路徑  // 具體貌似沒用
  • formData: 引數對應放到請求表單中

  第一種:將一個或多個引數保護API的“securityDefinitions”新增到生成的Swagger中。

這種是直接在文件的右上方新增一個 Authorize 按鈕,設定了值後,每一個請求都會在設定的位置上加上相應的值,在 上一篇隨筆中的 ConfigureServices 方法中,

對應位置 services.AddSwaggerGen(options =>{}) 中的  XmlComments  下 新增程式碼如下:

                options.AddSecurityDefinition("token", new ApiKeyScheme
                {
                    Description = "token format : {token}",//引數描述
                    Name = "token",//名字
                    In = "header",//對應位置
                    Type = "apiKey"//型別描述
                });
                options.AddSecurityDefinition("sid", new ApiKeyScheme
                {
                    Description = "sid format : {sid}",//引數描述
                    Name = "sid",//名字
                    In = "header",//對應位置
                    Type = "apiKey"//型別描述
                });
                //新增Jwt驗證設定 設定為全域性的,不然在程式碼中取不到
                options.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>> {
                    { "token", Enumerable.Empty<string>() },
                    { "sid", Enumerable.Empty<string>() },
                });

  新增完成後,執行起來看下效果,效果圖: 

 設定上對應值,呼叫測試方法,可以在header中取到剛設定到的值,

 這裡能看到,可以取到設定的引數了。這樣一來,在需要驗證的介面上,我們就可以通過介面文件來測試了。基本不用再借助postman等介面測試工具了。

但是,但是,這裡有一個問題,就是隻要設定了引數值,每一次訪問都會在請求中帶上引數。

下面將介紹第二種方式,只給需要驗證使用者的介面上新增驗證引數。

  第二種:使用“filters”擴充套件Swagger生成器,來實現只在需要新增引數的方法上新增引數。複雜的可以根據自己的需求來新增對應引數

實現方式就是先新建一個類,名: SwaggerParameter ,實現 IOperationFilter 介面。SwaggerParameter 類程式碼如下: 

    /// <summary>
    /// 自定義新增引數
    /// </summary>
    public class SwaggerParameter : IOperationFilter
    {
        /// <summary>
        /// 實現 Apply 方法
        /// </summary>
        /// <param name="operation"></param>
        /// <param name="context"></param>
        public void Apply(Operation operation, OperationFilterContext context)
        {
            if (operation.Parameters == null) operation.Parameters = new List<IParameter>();
            var attrs = context.ApiDescription.ActionDescriptor.AttributeRouteInfo;
            var t = typeof(BaseUserController);
            //先判斷是否是繼承使用者驗證類
            if (context.ApiDescription.ActionDescriptor is ControllerActionDescriptor descriptor && context.MethodInfo.DeclaringType?.IsSubclassOf(t) == true)
            {
                //再驗證是否允許匿名訪問
                var actionAttributes = descriptor.MethodInfo.GetCustomAttributes(inherit: true);
                bool isAnonymous = actionAttributes.Any(a => a is AllowAnonymousAttribute);
                // 需要驗證的方法新增
                if (!isAnonymous)
                {
                    operation.Parameters.Add(new NonBodyParameter()
                    {
                        Name = "sid",
                        In = "header", //query header body path formData
                        Type = "string",
                        Required = true,//是否必選
                        Description = "登入返回的sid"
                    });
                    operation.Parameters.Add(new NonBodyParameter()
                    {
                        Name = "token",
                        In = "header", //query header body path formData
                        Type = "string",
                        Required = true,//是否必選
                        Description = "登入返回的token"
                    });
                }
            }
        }
    }

 執行起來後,進入到 https://localhost:5001/apidoc/index.html 文件頁面,可以看到右上角的 Authorize 按鈕已經不見了,在不需要驗證的方法上,也找不到相應需要設定引數的輸入框。就只有在需要驗證的介面上才有。

參考Swagger文件圖如下: 

參考程式碼圖如下:

 

效果圖: 

  這樣一來設定也就完成了。從上面就能看出,就只有需要使用者驗證的接口才會有相應引數。 

 

我的設定方式是先定義了使用者驗證控制器類,讓需要使用者驗證的控制器繼承該控制器,然後在該控制器中不需要使用者驗證的介面上加上 AllowAnonymous 屬性 

設定fitter時就可以根據上面提到的兩個點來進行判斷是否需要加上引數,如果不是這樣實現的,可以根據自己的需求變更fitter類,來控制文件的生成。 

 

以上若有什麼不對或可以改進的地方,望各位指出或提出意見,一起探討學習~ 

有需要原始碼的可通過此 GitHub 連結拉取 覺得還可以的給個 start 和點個 下方的推薦哦~~謝