Swagger中添加Token验证

平常做项目使用mvc+webapi,采取前后端分离的方式,后台提供API接口给前端开发人员。这个过程中遇到一个问题后台开发人员怎么提供接口说明文档给前端开发人员。为了解决这个问题,项目中引用swagger(我比较喜欢戏称为“丝袜哥”)。

列出所有API控制器和控制器描述

outside_default.png

那么既然是api,肯定涉及到安全验证问题,那么怎么在测试文档增加添加Token安全验证呢;

下面我们来看看

1、定义swagger请求头

using Microsoft.AspNetCore.Authorization;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;


namespace CompanyName.ProjectName.HttpApi.Host.Code
{
    /// <summary>
    /// swagger请求头
    /// </summary>
    public class HttpHeaderOperationFilter : IOperationFilter
    {
        /// <summary>
        ///
        /// </summary>
        /// <param name="operation"></param>
        /// <param name="context"></param>
        public void Apply(Operation operation, OperationFilterContext context)
        {
            #region 新方法


            if (operation.Parameters == null)
            {
                operation.Parameters = new List<IParameter>();
            }


            if (context.ApiDescription.TryGetMethodInfo(out MethodInfo methodInfo))
            {
                if (methodInfo.CustomAttributes.All(t => t.AttributeType != typeof(AllowAnonymousAttribute))
                        && !(methodInfo.ReflectedType.CustomAttributes.Any(t => t.AttributeType == typeof(AuthorizeAttribute))))
                {
                    operation.Parameters.Add(new NonBodyParameter
                    {
                        Name = "Authorization",
                        In = "header",
                        Type = "string",
                        Required = true,
                        Description = "请输入Token,格式为bearer XXX"
                    });
                }
            }


            #endregion 新方法
        }
    }
}

2、在ConfigureServices方法添加OperationFilter

/// <summary>
        ///
        /// </summary>
        /// <param name="services"></param>
        // This method gets called by the runtime. Use this method to add services to the container.
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
            services.AddMvc().AddJsonOptions(options =>
              {
                  options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
                  options.SerializerSettings.Converters.Add(
                        new Newtonsoft.Json.Converters.IsoDateTimeConverter()
                        {
                            DateTimeFormat = "yyyy-MM-dd HH:mm:ss"
                        }
                      );
                  //小写
                  options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                  options.SerializerSettings.ContractResolver = new DefaultContractResolver();
                  //   //  options.SerializerSettings.DateFormatString = "yyyy-MM-dd";
              });
            //   services.AddMvc().AddXmlSerializerFormatters();
            //  services.AddMvc().AddXmlDataContractSerializerFormatters();
            services.AddLogging();
            services.AddCors(options =>
         options.AddPolicy("AllowSameDomain", builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()
     ));
            services.Configure<MvcOptions>(options =>
            {
                options.Filters.Add(new CorsAuthorizationFilterFactory("AllowSameDomain"));
            });


            #region Swagger


            services.AddSwaggerGen(c =>
          {
              c.SwaggerDoc("v1", new Info
              {
                  Version = "v1",
                  Title = "接口文档",
                  Description = "接口文档-基础",
                  TermsOfService = "https://example.com/terms",
                  Contact = new Contact
                  {
                      Name = "XXX1111",
                      Email = "XXX1111@qq.com",
                      Url = "https://example.com/terms"
                  }
                  ,
                  License = new License
                  {
                      Name = "Use under LICX",
                      Url = "https://example.com/license",
                  }
              });


              c.SwaggerDoc("v2", new Info
              {
                  Version = "v2",
                  Title = "接口文档",
                  Description = "接口文档-基础",
                  TermsOfService = "https://example.com/terms",
                  Contact = new Contact
                  {
                      Name = "XXX2222",
                      Email = "XXX2222@qq.com",
                      Url = "https://example.com/terms"
                  }
                   ,
                  License = new License
                  {
                      Name = "Use under LICX",
                      Url = "https://example.com/license",
                  }
              });
              c.OperationFilter<HttpHeaderOperationFilter>();
              c.DocumentFilter<HiddenApiFilter>();
              var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
              var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
              c.IncludeXmlComments(xmlPath);
              c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"CompanyName.ProjectName.ICommonServer.xml"));
          });


            #endregion Swagger


            #region MiniProfiler


            if (bool.Parse(Configuration["IsUseMiniProfiler"]))
            {
                //https://www.cnblogs.com/lwqlun/p/10222505.html
                services.AddMiniProfiler(options =>
    options.RouteBasePath = "/profiler"
 ).AddEntityFramework();
            }


            #endregion MiniProfiler


            services.AddDbContext<EFCoreDBContext>(options => options.UseMySql(Configuration["Data:MyCat:ConnectionString"]));
            var container = AutofacExt.InitAutofac(services, Assembly.GetExecutingAssembly());
            return new AutofacServiceProvider(container);
        }

3、定义一个ActionFilterAttribute

using CompanyName.ProjectName.Core;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Newtonsoft.Json;
using System.Security.Principal;


namespace CompanyName.ProjectName.HttpApi.Host
{
    /// <summary>
    /// 权限
    /// </summary>
    public class BasicAuth : ActionFilterAttribute
    {
        /// <summary>
        ///
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            if (context.HttpContext.Request != null && context.HttpContext.Request.Headers != null && context.HttpContext.Request.Headers["Authorization"].Count > 0)
            {
                var token = context.HttpContext.Request.Headers["Authorization"];
                if (string.IsNullOrWhiteSpace(token))
                {
                    ResultDto meta = ResultDto.Err("Unauthorized");
                    JsonResult json = new JsonResult(new
                    {
                        Meta = meta
                    }
                    );
                    JsonSerializerSettings jsetting = new JsonSerializerSettings();
                    jsetting.NullValueHandling = NullValueHandling.Ignore;
                    jsetting.Converters.Add(
                        new Newtonsoft.Json.Converters.IsoDateTimeConverter()
                        {
                            DateTimeFormat = "yyyy-MM-dd HH:mm:ss"
                        }
                    );
                    json.SerializerSettings = jsetting;
                    json.ContentType = "application/json; charset=utf-8";
                    context.Result = json;
                }
                else
                {
                    GenericIdentity ci = new GenericIdentity(token);
                    ci.Label = "conan1111111";
                    context.HttpContext.User = new GenericPrincipal(ci, null);
                }
            }
            else
            {
                ResultDto meta = ResultDto.Err("Unauthorized");
                JsonResult json = new JsonResult(new
                {
                    Meta = meta
                }
                );
                JsonSerializerSettings jsetting = new JsonSerializerSettings();
                jsetting.NullValueHandling = NullValueHandling.Ignore;
                jsetting.Converters.Add(
                    new Newtonsoft.Json.Converters.IsoDateTimeConverter()
                    {
                        DateTimeFormat = "yyyy-MM-dd HH:mm:ss"
                    }
                );
                json.SerializerSettings = jsetting;
                json.ContentType = "application/json; charset=utf-8";
                context.Result = json;
            }
            base.OnActionExecuting(context);
        }
    }
}

4、最后在需要的地方使用  [BasicAuth]

/// <summary>
        /// 添加
        /// </summary>
        /// <param name="model"></param>
        /// <returns>主键id</returns>
        [BasicAuth]
        [ModelValidationAttribute]
        [ApiExplorerSettings(GroupName = "v1")]
        [HttpPost, Route("Create")]
        public async Task<ResultDto<long>> CreateAsync([FromBody]CreateWebConfigDto model)
        {
            return await _webConfigApp.CreateAsync(model, new Core.CurrentUser());
        }

我们就可以看到Authorization - 请输入Token,格式为bearer XXX

outside_default.png

源码地址:

https://github.com/conanl5566/Sampleproject/tree/master/src/03%20Host/CompanyName.ProjectName.HttpApi.Host

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值