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

news2024/12/23 18:26:28

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/51325.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]Python计算机毕业设计Django付费自习室管理小程序

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;我…

vue项目使用elementui上传组件 打包后报错t.upload.addEventListener is not a function的解决方案

今天和大家分享一个报错的解决方案 背景 项目打包部署到宝塔上后&#xff0c;打开网页&#xff0c;上传东西时出现了一个报错&#xff0c;但是在本地开发环境是没有问题的。 报错内容&#xff1a; 这个问题是因为mockjs改动了axios里面XMLHttpRequest对象从而导致报错。 解…

Java医院信息管理系统源码带文字安装教程

技术架构 技术框架&#xff1a;springboot shiro layui jquery thymeleaf nginx 运行环境&#xff1a;jdk8 mysql IntelliJ IDEA maven 宝塔面板 文字安装教程 下载源码&#xff0c;创建一个数据库&#xff0c;导入hospitaldata.sql文件至数据库中。 使用IDEA打开hosp…

Kotlin高仿微信-第29篇-朋友圈-发布作品(图片)

Kotlin高仿微信-项目实践58篇详细讲解了各个功能点&#xff0c;包括&#xff1a;注册、登录、主页、单聊(文本、表情、语音、图片、小视频、视频通话、语音通话、红包、转账)、群聊、个人信息、朋友圈、支付服务、扫一扫、搜索好友、添加好友、开通VIP等众多功能。 Kotlin高仿…

GmNAC181促进结瘤并提高根瘤的耐盐性

文章信息 题目&#xff1a;GmNAC181 promotes symbiotic nodulation and salt tolerance of nodulation by directly regulating GmNINa expression in soybean 刊名&#xff1a;New Phytologist 作者&#xff1a;Xiaodi Wang&#xff0c;Youning Wang, Xia Li et al. 单位…

2022年NPDP新版教材知识集锦--【第四章节】(5)

《产品经理认证(NPDP)知识体系指南(第2版)》已于2022年4月正式上架发行&#xff0c;新版教材自2022年11月NPDP考试起使用。将新版NPDP教材中的相关知识点进行了整理汇总&#xff0c;包括详细设计与规格阶段相关内容&#xff0c;快来看看吧。 【详细设计与规格阶段】(全部获取文…

HCIP-路由01:路由基础

路由基础一 自治系统&#xff08;AS&#xff09;二. 入表&#xff08;路由表&#xff09;规则2.1 priority2.2 metric三. 选路规则&#xff08;掩码最长匹配原则&#xff09;四. 路由的负载分担五. 路由备份&#xff08;浮动路由&#xff09;六. 路由黑洞七. 路由黑洞的解决方法…

export default 和 export之间的区别

&#x1f388; export default 和 export 有什么区别&#xff1a; export 、export default&#xff0c;都属于ES6里面的语法 1. export与export default均可用于导出常量、函数、文件、模块等 2. 你可以在其它文件或模块中通过import(常量 | 函数 | 文件 | 模块)名的方式&a…

03【Controller方法返回值详解】

文章目录三、Controller方法返回值详解3.1 返回普通字符串3.1.1 跳转3.1.2 设置视图解析器3.2 返回ModelAndView3.2.1 普通视图3.2.2 RedirectView3.3 返回特殊字符串3.4 返回void三、Controller方法返回值详解 3.1 返回普通字符串 3.1.1 跳转 package com.dfbz.controller;…

美颜预览卡顿问题跟踪

预览卡顿的问题&#xff0c;首先第一想法就是看下帧率&#xff0c;帧率小&#xff0c;自然会卡顿。根据人眼视觉暂留原理&#xff0c;帧率小于24帧&#xff0c;人脸就会感知到卡顿。 帧率的概念在Camera中我们经常会提到&#xff0c;其实有3个帧率概念&#xff0c;从下往常看&a…

1-5-10 快恢在数字化安全生产平台 DPS 中的设计与落地

作者&#xff1a;银桑 背景 11 月 5 日&#xff0c;在 2022 杭州 云栖大会上&#xff0c;数字化安全生产平台 DPS 重磅发布&#xff0c;助力传统运维向 SRE 转型&#xff0c;在数字化安全生产平台 DPS 重磅发布中提到了 DPS 诞生的背景&#xff0c;希望解决的企业问题以及核…

ICC2: secondary pg pin的作用与连接

1.secondary pg pin的作用 1&#xff09; 作为备用电源&#xff08;backup power&#xff09;&#xff0c;当主供电&#xff08;primary power&#xff09;断电后&#xff0c;让standard cell仍能保持正常运行或者至少保持输出不变&#xff0c;比如always on buf和retention r…

【矩阵论】4. 矩阵运算——广义逆——加号逆应用

4.4.3 矩阵方程求解 前置&#xff1a;正规方程 a. 有解情况 若矩阵方程 AXBDAXBDAXBD 有解相容&#xff0c;则有特解 X0ADBX_0A^DB^X0​ADB 无解定理&#xff1a;若 X0ADBX_0A^DB^X0​ADB &#xff0c;使 AX0B≠DAX_0B\neq DAX0​B​D &#xff0c;则矩阵方程无解 齐次方程…

【学习笔记】深度学习入门:基于Python的理论与实现-神经网络

CONTENTS三、神经网络3.1 从感知机到神经网络3.2 Activation function3.3 多维数组的运算3.4 三层神经网络的实现3.5 输出层的设计3.6 手写数字识别三、神经网络 3.1 从感知机到神经网络 用图来表示神经网络的话&#xff0c;如下图所示&#xff0c;我们把最左边的一列称为输入…

Open WebRTC Toolkit Native SDK Windows环境编译

1、首先按照编译webrtc原生代码环境&#xff0c;配置系统环境 https://chromium.googlesource.com/chromium/src//main/docs/windows_build_instructions.mdhttps://chromium.googlesource.com/chromium/src//main/docs/windows_build_instructions.md 安装openssl软件/s…

MODBUS协议下,能否实现MCGS触摸屏与FX5U之间无线通讯?

在工厂里&#xff0c;触摸屏往往位于程控室内&#xff0c;作为控制多个不同位置PLC的主站设备。因为触摸屏和plc所处位置距离较为分散&#xff0c;重新铺设电缆线工期长&#xff0c;成本高&#xff0c;故采用无线方式解决触摸屏与PLC之间的通讯问题。 一、方案概述 本方案是M…

年底了,准备跳槽的可以看看

前两天跟朋友感慨&#xff0c;今年的铜九铁十、裁员、疫情导致好多人都没拿到offer!现在已经12月了&#xff0c;具体明年的金三银四只剩下两个月。 对于想跳槽的职场人来说&#xff0c;绝对要从现在开始做准备了。这时候&#xff0c;很多高薪技术岗、管理岗的缺口和市场需求也…

【Linux03-基本工具之VIM】Linux下的强大编辑器(附软件生态与yum)

前言 本期分享6个Linux中常用的基本工具&#xff0c;以确保后续的学习能够进行。 零、软件生态与yum 抛出一个问题&#xff1a;软件的下载&#xff1f; 具体拆分 软件从哪里下&#xff1f;软件由谁提供&#xff1f;怎么下载&#xff1f; 软件&#xff0c;肯定不在本地&am…

RabbitMQ死信队列、延时队列

介绍&#xff1a; 消息被消费⽅否定确认&#xff0c;使⽤ channel.basicNack 或 channel.basicReject &#xff0c;并且此时 requeue 属性被设置为 false 。消息在队列的存活时间超过设置的TTL时间。消息队列的消息数量已经超过最⼤队列⻓度。那么该消息将成为“死信”。“死信…

Espresso Sequencer:去中心化Rollups

1. 引言 前序博客有&#xff1a; HyperPlonk——实现zkEVM的一种zk-proof system Espresso Systems团队致力于为Web3世界开发工具和基础设施。 Espresso Sequencer&#xff1a;为在不牺牲扩展性和速度的情况下&#xff0c;实现的去中心化rollups系统&#xff0c;兼具Web2的性…