یک نکتهی تکمیلی: نشان دادن لیست APIها در swagger فقط برای کاربرانی که لاگین کرده اند در هنگام توسعهی پروژه شاید برای شما مهم باشد که لیست apiهای شما برای افرادی که لاگین نکردهاند، قابل مشاهده نباشد. برای این منظور ابتدا باید سه کتابخانه مربوط به swagger را نصب نمایید:
سپس یک کلاس را همراه با دو اکستنشن متد برای کانفیگ swagger میسازیم :
در متد AddSwaggerGen از DocumentFilter استفاده کردهایم. با استفاده از Document FIlterها میتوانید خروجی apiها را در swagger، توسعه دهید. DocumentFilter که از نوع جنریک است، یک کلاس را به عنوان تایپ قبول میکند که باید از اینترفیس IDocumentFilter ارث بری کرده باشد. اینترفیس IDocumentFilter حاوی یک متد Apply است که دارای دو ورودی از نوع SwaggerDocument و DocumentFilterContext میباشد. کلاس SwaggerDocument مستندات apiها را در اختیار شما قرار میدهد و میتوانید آنهارا تغییر دهید.
در کلاس AuthenticationDocumentFilter از IHttpContextAccessor برای دسترسی به هویت کاربر استفاده کرده ایم که بعدا باید در متد ConfigureService متد AddHttpContextAccessor را جهت دسترسی به IHttpContextAccessor فراخوانی کنیم. در ادامه اگر کاربر لاگین نکرده باشد، تمامی apiها پاک شده و در سمت کاربر هیچ api ای مشاهده نمیشود.
و اضافه کردن میان افزار swagger :
<PackageReference Include="Swashbuckle.AspNetCore" Version="4.0.1" /> <PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="4.0.1" /> <PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="4.5.2" />
public static class ServiceCollectionExtensions { public static void AddCustomSwagger(this IServiceCollection services) { services.AddSwaggerGen(options => { options.EnableAnnotations(); options.DocumentFilter<AuthenticationDocumentFilter>(); options.SwaggerDoc("v1", new Info { Version = "v1", Title = "Test API" }); }); } public static void UseSwaggerAndUI(this IApplicationBuilder app) { app.UseSwagger(); app.UseSwaggerUI(options => { options.DocExpansion(DocExpansion.None); options.SwaggerEndpoint("/swagger/v1/swagger.json", "Test API Docs"); }); } }
سپس کلاس AuthenticationDocumentFilter را پیاده سازی میکنیم:
public class AuthenticationDocumentFilter : IDocumentFilter { private readonly IHttpContextAccessor httpContextAccessor; public AuthenticationDocumentFilter(IHttpContextAccessor httpContextAccessor) { this.httpContextAccessor = httpContextAccessor; } public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context) { if (!httpContextAccessor.HttpContext.User.Identity.IsAuthenticated) { swaggerDoc.Definitions = new Dictionary<string, Schema>(); swaggerDoc.Paths = new Dictionary<string, PathItem>(); } } }
در صورت نیاز میتوان مشخص کرد کدام نوع api هارا نشان ندهد؛ به عنوان مثال Post و Put را نشان ندهد :
public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context) { if (!httpContextAccessor.HttpContext.User.Identity.IsAuthenticated) { foreach (var item in swaggerDoc.Paths) { item.Value.Post = null; item.Value.Put = null; } } }
در ادامه برای ثبت سرویسها در کلاس StartUp
public void ConfigureServices(IServiceCollection services) { services.AddHttpContextAccessor(); services.AddAuthorization(); services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(options=> { options.AccessDeniedPath = "/Login"; options.Cookie.HttpOnly = true; options.LoginPath = "/Login"; options.LogoutPath = "/Login"; options.ExpireTimeSpan = TimeSpan.FromDays(15); options.SlidingExpiration = true; options.Cookie.IsEssential = true; options.ReturnUrlParameter = "returnUrl"; }); services.AddMvc(); services.AddCustomSwagger(); }
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseAuthentication(); app.UseSwaggerAndUI(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }