第8章 自定义SwaggerIndex页与登录页

“Blog.Core-master”程序没有使用.Net7框架内置的index.html页对api方法进行渲染显示,而是通过对“Swagger”和“SwaggerUI”内置中间件的自定义操作,调用根目录下的自定义index.html页对api方法进行渲染显示。

1、自定义“Swagger”和“SwaggerUI”内置中间件和index.html页

1.1 自定义“Swagger”和“SwaggerUI”内置中间件

using System;

using System.IO;

using System.Linq;

using Common.Helper;

using log4net;

//Nuget--Swashbuckle.AspNetCore

using Microsoft.AspNetCore.Builder;

//using static Blog.Core.Extensions.CustomApiVersion;

namespace Extensions.ServiceExtensions

{

    /// <summary>

    /// 【Swagger中间件】

    /// <remarks>

    /// 摘要:

    ///     通过该类中的方法成员把“UseSwagger”管道中间件,集成到.Net7框架内置管道中,为页面渲染显示api提供支撑。

    /// </remarks>

    /// </summary>

    public static class SwaggerMiddleware

    {

        private static readonly ILog Log = LogManager.GetLogger(typeof(SwaggerMiddleware));

        public static void UseSwaggerMiddle(this IApplicationBuilder app, Func<Stream> streamHtml)

        {

            if (app == null) throw new ArgumentNullException(nameof(app));

            //把“UseSwagger”管道中间件,集成到.Net7框架内置管道中。

            app.UseSwagger();

            //通过自定义设置“UseSwaggerUI”管道中间件,并集成到.Net7框架内置管道中,为页面渲染显示api提供支撑。

            app.UseSwaggerUI(c =>

            {

                //根据版本名称倒序 遍历展示

                //var apiName = AppSettings.app(new string[] { "Startup", "ApiName" });

                //typeof(ApiVersions).GetEnumNames().OrderByDescending(e => e).ToList().ForEach(version =>

                //{

                //    c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"{apiName} {version}");

                //});

                //c.SwaggerEndpoint($"https://petstore.swagger.io/v2/swagger.json", $"{apiName} pet");

                // 将swagger展示api首页,设置成我们自定义的页面(这里特指:WebApi\index.html,记得这个字符串的写法:{项目名.index.html}

                if (streamHtml.Invoke() == null)

                {

                    var msg = "index.html的属性,必须设置为:“嵌入的资源”";

                    Log.Error(msg);

                    throw new Exception(msg);

                }

                c.IndexStream = streamHtml;

                //if (Permissions.IsUseIds4)

                //{

                //    c.OAuthClientId("blogadminjs");

                //}

                // 注意路径配置,设置为空,表示对根目录下的文件(这里特指:WebApi\index.html)进行访问;如果不定义正面的语句将会出现“404”错误。

                c.RoutePrefix = "";

            });

        }

    }

}

1.2自定义根目录Index.html页

    注意:1、根目录Index.html页面的属性必须被设定为:“嵌入的资源”,如下图所示;

 

2、注释掉“launchSettings.json”文件中的"launchUrl"节点;或把“"launchUrl": "swagger"”修改为:“"launchUrl": "indexer.html"” ,如下图所示;

1.3 重构Program类

var app = builder.Build();

//把自定义管道中间件集成到.Net(Core)框架内置管道中,解决vue/uni-app前端项目(Cors)访问当前后端项目时,浏览器或App中出现的异常:

//    1“has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.”

//    2“has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.”

app.UseMiddleware<CorsMiddleware>();

//把自定义“UseSwagger”“UseSwaggerUI”管道中间件集成到.Net7框架内置管道中,为自定义“index.html”页面渲染显示api提供支撑。

app.UseSwaggerMiddle(() => Assembly.GetExecutingAssembly().GetManifestResourceStream("WebApi.index.html"));


    按F5执行程序如下图所示:

2 自定义“UseSwaggerAuthorized”中间件和swg-login.html页  
2.1 复制资源文件到“wwwroot”目录,如下图所示:

2.2 自定义UseSwaggerAuthorized中间件

using System.Net;

using Microsoft.AspNetCore.Builder;

using Microsoft.AspNetCore.Http;

namespace Extensions.ServiceExtensions

{

    /// <summary>

    /// 【Swagger授权中间件】

    /// </summary>

    /// <remarks>

    /// 摘要:

    ///     该管道中间件类主要用于判断1个指定用户是否已经被授权,如果已经被授权则直接访问默认启动页面;反之跳转到登录页面。

    /// </remarks>

    public class SwaggerAuthMiddleware

    {

        #region 拷贝构造方法与变量

        /// <summary>

        /// 【下1个】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///     .Net(Core)框架内置管道中的下1个管道中间件实例。

        /// </remarks>

        private readonly RequestDelegate next;

        ///<param name="next">.Net(Core)框架内置管道中的下1个管道中间件实例。</param>

        /// <summary>

        /// 【拷贝构造方法】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///    通过该构造方法中的参数实例,实例化.Net(Core)框架内置管道中的下1个管道中间件实例。

        /// </remarks>

        public SwaggerAuthMiddleware(RequestDelegate next)

        {

            this.next = next;

        }

        #endregion

        #region 方法

        ///<param name="context">HTTP上下文实例。</param>

        /// <summary>

        /// 【异步调用】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///    通过该方法向.Net(Core)框架内置管道中集成当前管道中间件,判断1个指定用户是否已经被授权,如果已经被授权则直接访问默认启动页面;反之跳转到登录页面:

        /// </remarks>

        public async Task InvokeAsync(HttpContext context)

        {

            // 也可以根据是否是本地做判断 IsLocalRequest。

            // 说明:该“index.html”页面即不是根目录中的“index.html”页面;也不是“wwwroot”目录中的“index.html”页面,它是“Swagger”中间件内置的“index.html”页面。

            //所以只要当前程序集成了“Swagger”中间件,下面1行语句的值总为:true。

            if (context.Request.Path.Value.ToLower().Contains("index.html"))

            {

                // 判断权限是否正确

                if (IsAuthorized(context))

                {

                    await next.Invoke(context);

                    return;

                }

                // 无权限,跳转swagger登录页

                context.Response.Redirect("/swg-login.html");

            }

            else

            {

                await next.Invoke(context);

            }

        }

        ///<param name="context">HTTP上下文实例。</param>

        /// <summary>

        /// 【已授权?】

        /// <remarks>

        /// 摘要:

        ///     通过对服务器端的“session”中指定信息的匹配操作,获取1个值false(未授权)/true(已授权),该值指示指定用户是否已经被授权。

        /// </remarks>

        /// <returns>

        /// 返回:

        ///     1个值false(未授权)/true(已授权)。

        /// </returns>

        /// </summary>

        public bool IsAuthorized(HttpContext context)

        {

            // 使用session模式

            // 可以使用其他的

            return context.Session.GetString("swagger-code") == "success";

        }

        ///<param name="context">HTTP上下文实例。</param>

        /// <summary>

        /// 【本地请求?】

        /// <remarks>

        /// 摘要:

        ///     获取1个值false(非本地请求)/true(本地请求),该值指示指定请求是否是本地请求,如果不是swagger中间件将自动执行拦截操作。

        /// 注意:

        ///     该方法原程序中没有任何对象进行调用,如果简化定义实现可以直接删除掉。

        /// </remarks>

        /// <returns>

        /// 返回:

        ///    1个值false(非本地请求)/true(本地请求)

        /// </returns>

        /// </summary>

        public bool IsLocalRequest(HttpContext context)

        {

            if (context.Connection.RemoteIpAddress == null && context.Connection.LocalIpAddress == null)

            {

                return true;

            }

            if (context.Connection.RemoteIpAddress.Equals(context.Connection.LocalIpAddress))

            {

                return true;

            }

            if (IPAddress.IsLoopback(context.Connection.RemoteIpAddress))

            {

                return true;

            }

            return false;

        }

        #endregion

    }

    /// <summary>

    /// 【Swagger授权中间件扩展】

    /// </summary>

    /// <remarks>

    /// 摘要:

    ///     通过该类中的方法成员把Swagger授权中间件集成到.Net7框架的内置管道中,以实现,如果已经被授权则直接访问默认启动页面;反之跳转到登录页面。

    /// </remarks>

    public static class SwaggerAuthorizeExtensions

    {

        public static IApplicationBuilder UseSwaggerAuthorized(this IApplicationBuilder builder)

        {

            return builder.UseMiddleware<SwaggerAuthMiddleware>();

        }

    }

}

2.3 重构Program类

//必须在把下面的1行定义上否则会出现异常:““An exception was thrown while activating Microsoft.AspNetCore.Session.DistributedSessionStore.”“An exception was thrown while activating Microsoft.AspNetCore.Session.DistributedSessionStore.””

builder.Services.AddDistributedMemoryCache();

//“Session”中间件实例,依赖注入到.Net(Core)7框架内置容器中。

builder.Services.AddSession();

builder.Services.AddControllers();

app.UseMiddleware<CorsMiddleware>();

app.UseSession();

//把自定义“Swagger”授权管道中间件集成到.Net7框架内置管道中,以实现,如果已经被授权则直接访问默认启动页面;反之跳转到登录页面。

app.UseSwaggerAuthorized();

//把自定义“UseSwagger”“UseSwaggerUI”管道中间件集成到.Net7框架内置管道中,为自定义“index.html”页面渲染显示api提供支撑。

app.UseSwaggerMiddle(() => Assembly.GetExecutingAssembly().GetManifestResourceStream("WebApi.index.html"));

//设定“wwwroot”目录中的“index.html”页面,为默认启动页。

DefaultFilesOptions defaultFilesOptions = new DefaultFilesOptions();

defaultFilesOptions.DefaultFileNames.Clear();

// 说明:该“index.html”页面即不是根目录中的“index.html”页面;也不是“Swagger”中间件内置的“index.html”页面,它是“wwwroot”目录中的“index.html”页面。

//实际上原程序是以根目录中的“index.html”页面,为默认启动页,为了简化定义实现本从并没有复制“wwwroot”目录中的“index.html”页面。

defaultFilesOptions.DefaultFileNames.Add("index.html");

app.UseDefaultFiles(defaultFilesOptions);

app.UseStaticFiles();

按F5执行程序如下图所示:

对以上功能更为具体实现和注释见:221201_07Blog(自定义SwaggerIndex页与登录页)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值