یک نکتهی تکمیلی: نشان دادن لیست APIها در swagger فقط برای کاربرانی که لاگین کرده اند در هنگام توسعهی پروژه شاید برای شما مهم باشد که لیست 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" />
سپس یک کلاس را همراه با دو اکستنشن متد برای کانفیگ swagger میسازیم :
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");
});
}
}
در متد AddSwaggerGen از DocumentFilter استفاده کردهایم. با استفاده از Document FIlterها میتوانید خروجی apiها را در swagger، توسعه دهید. DocumentFilter که از نوع جنریک است، یک کلاس را به عنوان تایپ قبول میکند که باید از اینترفیس IDocumentFilter ارث بری کرده باشد. اینترفیس IDocumentFilter حاوی یک متد Apply است که دارای دو ورودی از نوع SwaggerDocument
و DocumentFilterContext میباشد. کلاس SwaggerDocument مستندات apiها را در اختیار شما قرار میدهد و میتوانید آنهارا تغییر دهید. سپس کلاس 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>();
}
}
}
در کلاس AuthenticationDocumentFilter از IHttpContextAccessor برای دسترسی به هویت کاربر استفاده کرده ایم که بعدا باید در متد ConfigureService متد AddHttpContextAccessor
را جهت دسترسی به IHttpContextAccessor فراخوانی کنیم. در ادامه اگر کاربر لاگین نکرده باشد، تمامی apiها پاک شده و در سمت کاربر هیچ api ای مشاهده نمیشود. در صورت نیاز میتوان مشخص کرد کدام نوع 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();
}
و اضافه کردن میان افزار swagger :
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?}");
});
}