.NET Core 使用Swagger並啟用API文檔的JWT授權


一、概述

剛參加工作時,寫個API接口,還要寫API文檔,再使用PostMan測試接口,寫文檔的時間比寫接口還要折騰。后來接觸Swagger,API文檔的工作得到了很大的改善,不但可以自動構建交互式API說明文檔,還能直接調試API接口。今天記錄下Core項目下使用Swagger,最新版的Swagger已經完美支持Open Api規范及JWT Token授權訪問等。使用Swagger的好處總結如下:

  • 使用 Swagger 生成精美的API接口文檔
  • 使用 Swagger 調試JWT授權接口
  • 使用 Swagger 生成各個類庫中視圖模型的描述

二、配置Swagger服務

1、引用Nuget包

新建一個.NET Core 3.1 Web Api 項目,打開Nuget安裝管理器,搜索Swashbuckle.AspNetCore,安裝即可

2、配置服務

我們打開Startup.cs文件,來對Swagger配置進行一些必要的配置,在ConfigureServices方法我們添加一下Swagger配置:

public void ConfigureServices(IServiceCollection services)
{

  services.AddControllers();
  services.AddSwaggerGen(c =>
  {
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Core.Api", Version = "v1" });
  });
}

然后我們在Configure方法里添加swagger中間件:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
  if (env.IsDevelopment())
  {
    app.UseDeveloperExceptionPage();
    app.UseSwagger();
    app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Core.Api v1"));
  }

  app.UseHttpsRedirection();

  app.UseRouting();

  app.UseAuthorization();

  app.UseEndpoints(endpoints =>
  {
  endpoints.MapControllers();
  });
}

這樣swagger基本配置就完成了,看下效果

3、忽略注釋警告

F5運行項目后發現有很多警告:

原因是是swagger把一些 action 方法都通過xml文件配置了,如果沒有加入相應的注釋就會警告。如果不想每一個方法都加注釋,可以如下配置:選擇項目,右鍵屬性,選擇生成菜單,加入;1591

4、為接口添加注釋

右鍵項目名稱=>屬性=>生成,勾選“輸出”下面的“xml文檔文件”,系統會默認生成一個xml。

此時項目中會生成一個 Core.Api.xml文件,修改該文件屬性,選擇較新則復制。然后修改下startup.cs中的ConfigureServices方法:

public void ConfigureServices(IServiceCollection services)
{
  services.AddControllers();
  services.AddSwaggerGen(c =>
  {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "Core.Api", Version = "v1" });
        // 為 Swagger JSON and UI設置xml文檔注釋路徑
        //獲取應用程序所在目錄(絕對,不受工作目錄影響,建議采用此方法獲取路徑)
        var basePath = AppContext.BaseDirectory;
        var xmls = Directory.GetFiles(basePath, "*.xml");
        foreach (var aXml in xmls)
        {
            c.IncludeXmlComments(aXml);
        }
   });
}

然后action方法上加入注釋:

/// <summary>
/// 獲取數據
/// </summary>
/// <returns></returns>
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
     var rng = new Random();
     return Enumerable.Range(1, 5).Select(index => new WeatherForecast
     {
           Date = DateTime.Now.AddDays(index),
           TemperatureC = rng.Next(-20, 55),
           Summary = Summaries[rng.Next(Summaries.Length)]
      })
      .ToArray();
}

看下效果:

5、為Model 添加注釋

新建一個model,加入字段注釋

public class StudentModel
{
  /// <summary>
  /// 標識
  /// </summary>
  public int ID { get; set; }
  /// <summary>
  /// 姓名
  /// </summary>
  public string Name { get; set; }
}

為model所在的項目也要配置xml,類似於上述第三步

//注入model 的xml 
var xmlModelPath = Path.Combine(basePath, "xx.Model.xml");//這個就是Model層的xml文件名 c.IncludeXmlComments(xmlModelPath);

控制器中引用:

/// <summary>
/// 插入學生信息
/// </summary>
/// <param name="studentModel">model實體類參數</param>
/// <returns></returns>
[HttpPost]
public bool Insert([FromQuery] StudentModel studentModel)
{
  return true;
}

效果如下:

6、隱藏接口

如果不想顯示某些接口,直接在controller 上,或者action 上,增加特性可隱藏接口

[ApiExplorerSettings(IgnoreApi = true)]

7、Swagger啟用API文檔的JWT授權

目前很多網站都使用了JWT(JSON WEB TOKEN)來作為賬戶系統的認證授權,JWT以它的簡單、高效、分布式優勢很快成為了網站的流行驗證方式。接下來我們為Swagger添加JWT授權認證,依舊打開Startup.cs文件,修改上面ConfigureServices方法中的代碼:

public void ConfigureServices(IServiceCollection services)
{

  services.AddControllers();
  services.AddSwaggerGen(c =>
  {
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Core.Api", Version = "v1" });

    #region 加載xml
    // 為 Swagger JSON and UI設置xml文檔注釋路徑
    //獲取應用程序所在目錄(絕對,不受工作目錄影響,建議采用此方法獲取路徑)
    var basePath = AppContext.BaseDirectory;
    var xmls = Directory.GetFiles(basePath, "*.xml");
    foreach (var aXml in xmls)
    {
      c.IncludeXmlComments(aXml);
    }
    #endregion

    #region jwt認證
    // 開啟加權小鎖
    c.OperationFilter<AddResponseHeadersFilter>();
    c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();
    // 在header中添加token,傳遞到后台
    c.OperationFilter<SecurityRequirementsOperationFilter>();
    // Jwt Bearer 認證
    c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
    {
      Name = "Authorization",//jwt默認的參數名稱
      In = ParameterLocation.Header,//jwt默認存放Authorization信息的位置(請求頭中)
      Type = SecuritySchemeType.ApiKey,
      Description = "Authorization:Bearer {your JWT token},注意兩者之間是一個空格",
    });
    #endregion
  });
}

預覽一下授權設置,發現右側多了一個Authorize綠色的帶鎖按鈕,這個按鈕點開后就可以設置我們的JWT Token信息了,格式是:Bearer 你的Token字符串,注意Bearer於Token之間有個空格。設置好Token后,你請求任意的API接口時,Swagger會自動附帶Token到請求的Header中。

既然swagger中支持了jwt認證,那么我們在startup.cs中啟用jwt認證:如下

     public void ConfigureServices(IServiceCollection services)
        {

            services.AddControllers();
            #region 開啟jwt認證
            var symmetricKeyAsBase64 = "!@#123";
            var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
            var signingKey = new SymmetricSecurityKey(keyByteArray);
            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(o =>
            {
                o.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = signingKey,
                    ValidateIssuer = true,
                    ValidIssuer = "asd",//發行人
                    ValidateAudience = true,
                    ValidAudience = "fdf",//訂閱人
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.Zero,//這個是緩沖過期時間,也就是說,即使我們配置了過期時間,這里也要考慮進去,過期時間+緩沖
                    RequireExpirationTime = true,
                };

            });
            #endregion
            #region 配置swagger文檔
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "Core.Api", Version = "v1" });

                #region 加載xml
                // 為 Swagger JSON and UI設置xml文檔注釋路徑
                //獲取應用程序所在目錄(絕對,不受工作目錄影響,建議采用此方法獲取路徑)
                var basePath = AppContext.BaseDirectory;
                var xmls = Directory.GetFiles(basePath, "*.xml");
                foreach (var aXml in xmls)
                {
                    c.IncludeXmlComments(aXml);
                }
                #endregion

                #region jwt認證
                // 開啟加權小鎖
                c.OperationFilter<AddResponseHeadersFilter>();
                c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();
                // 在header中添加token,傳遞到后台
                c.OperationFilter<SecurityRequirementsOperationFilter>();
                // Jwt Bearer 認證
                c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
                {
                    Name = "Authorization",//jwt默認的參數名稱
                    In = ParameterLocation.Header,//jwt默認存放Authorization信息的位置(請求頭中)
                    Type = SecuritySchemeType.ApiKey,
                    Description = "Authorization:Bearer {your JWT token},注意兩者之間是一個空格",
                });
                #endregion
            });
            #endregion
        }

更詳細關於jwt認證的這里就不細講了

8、默認直接訪問swagger

有時候打開webapi項目,希望直接打開swagger文檔,有兩種方法:

  • 方法一:設置launchSettings.json文件中的launchUrl屬性,指定為swagger,如下:

  • 方法二我們可以通過RoutePrefix 屬性設置。
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "Core.Api v1");
    c.RoutePrefix = ""; //路徑配置,設置為空,表示直接在根域名訪問swagger文件
});

建議使用方法二。

三、Swagger異常匯總

1、問題一

如果出現如上圖那樣的錯誤,請打開swagger/v1/swagger.json查看具體原因。 常見的原因是action上沒有加入HTTP請求協議,比如[HttpPost]

2、問題二

這是因為接口json文檔定義和調用不是一個,請仔細對比下定義和調用的swagger名稱是否一致。比如定義的時候名稱為“v1”:

 c.SwaggerDoc("v1", new OpenApiInfo { Title = "Core.Api", Version = "v1" });

調用的時候也要保證一致:

app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Core.Api v1")); 

3、問題三

上圖錯誤是路由重載導致的,請確保不要存在多個一樣的路由。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM