第8章 自定义SwaggerIndex页与登录页
创始人
2024-03-06 20:37:33
0次

“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

{

    ///

    /// 【Swagger中间件】

    ///

    /// 摘要:

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

    ///

    ///

    public static class SwaggerMiddleware

    {

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

        public static void UseSwaggerMiddle(this IApplicationBuilder app, Func 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();

//把自定义“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

{

    ///

    /// 【Swagger授权中间件】

    ///

    ///

    /// 摘要:

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

    ///

    public class SwaggerAuthMiddleware

    {

        #region 拷贝构造方法与变量

        ///

        /// 【下1个】

        ///

        ///

        /// 摘要:

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

        ///

        private readonly RequestDelegate next;

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

        ///

        /// 【拷贝构造方法】

        ///

        ///

        /// 摘要:

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

        ///

        public SwaggerAuthMiddleware(RequestDelegate next)

        {

            this.next = next;

        }

        #endregion

        #region 方法

        ///HTTP上下文实例。

        ///

        /// 【异步调用】

        ///

        ///

        /// 摘要:

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

        ///

        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);

            }

        }

        ///HTTP上下文实例。

        ///

        /// 【已授权?】

        ///

        /// 摘要:

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

        ///

        ///

        /// 返回:

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

        ///

        ///

        public bool IsAuthorized(HttpContext context)

        {

            // 使用session模式

            // 可以使用其他的

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

        }

        ///HTTP上下文实例。

        ///

        /// 【本地请求?】

        ///

        /// 摘要:

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

        /// 注意:

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

        ///

        ///

        /// 返回:

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

        ///

        ///

        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

    }

    ///

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

    ///

    ///

    /// 摘要:

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

    ///

    public static class SwaggerAuthorizeExtensions

    {

        public static IApplicationBuilder UseSwaggerAuthorized(this IApplicationBuilder builder)

        {

            return builder.UseMiddleware();

        }

    }

}

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();

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页与登录页)。

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...