【第22章】Spring Cloud之Gateway集成Knife4j(下)

news2024/11/10 2:33:29

文章目录

  • 前言
  • 一、访问页面加权控制
    • 1. 加权控制
    • 2. 登录
  • 二、生产环境如何屏蔽Knife4j、Swagger等Ui资源和接口
    • 1. 基于Spring Boot框架提供的@Conditional条件控制相关@Bean的生效
    • 2. 效果
  • 三、聚合个性化配置
    • 1. 用户服务
      • 1.1 引入依赖
      • 1.2 Knife4j配置类
      • 1.3 控制器
    • 2. 网关服务
      • 2.1 排除用户服务
      • 2.2 定义新用户服务路由
      • 2.3 手动聚合分组
    • 3. 效果展示
  • 总结


前言

上一章已经完成了在网关层集成Knife4j,这里来做一些Knife4j常用功能的使用。


一、访问页面加权控制

上一章我们通过访问地址,就直接访问到了文档界面,这样做是不安全的,我们需要添加基本的权限控制,官方已经提供了此功能,我们完成配置并开启即可。

1. 加权控制

在这里插入图片描述
注意basic的层级是在gateway下面的

knife4j:
  gateway:
    # ① 第一个配置,开启gateway聚合组件
    enabled: true
    # ② 第二行配置,设置聚合模式采用discover服务发现的模式
    strategy: discover
    discover:
      # ③ 第三行配置,开启discover模式
      enabled: true
      # ④ 第四行配置,聚合子服务全部为OpenAPI3规范的文档
      version: openapi3
    basic:
      enable: true
      # Basic认证用户名
      username: admin
      # Basic认证密码
      password: admin

2. 登录

在这里插入图片描述
在这里插入图片描述

二、生产环境如何屏蔽Knife4j、Swagger等Ui资源和接口

这是个老生常谈的问题了,开发环境对外开放接口和静态ui资源,没有问题,但是生产为了保护应用程序安全,建议对接口拦截屏蔽

1. 基于Spring Boot框架提供的@Conditional条件控制相关@Bean的生效

Spring Boot配置起来很方便,简单地配置开关即可

在这里插入图片描述

knife4j:
  gateway:
    # ① 第一个配置,开启gateway聚合组件
    enabled: false
    # ② 第二行配置,设置聚合模式采用discover服务发现的模式
    strategy: discover
    discover:
      # ③ 第三行配置,开启discover模式
      enabled: true
      # ④ 第四行配置,聚合子服务全部为OpenAPI3规范的文档
      version: openapi3
    basic:
      enable: true
      # Basic认证用户名
      username: admin
      # Basic认证密码
      password: admin

2. 效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可以看出,我们的配置已经生效,生产环境上线时,
修改配置knife4j.gateway.enabled: false进行关闭,避免接口泄漏,造成安全问题

三、聚合个性化配置

这里我们对用户服务做个性化配置

1. 用户服务

1.1 引入依赖

<!-- https://mvnrepository.com/artifact/com.github.xiaoymin/knife4j-openapi3-jakarta-spring-boot-starter -->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
    <version>4.5.0</version>
</dependency>

1.2 Knife4j配置类

package org.example.user.config;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springdoc.core.customizers.GlobalOpenApiCustomizer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * Create by zjg on 2024/8/4
 */
@Configuration
public class Knife4jConfiguration {
    @Value("${server.port}")
    private int port;
    /**
     * 根据@Tag 上的排序,写入x-order
     *
     * @return the global open api customizer
     */
    @Bean
    public GlobalOpenApiCustomizer orderGlobalOpenApiCustomizer() {
        return openApi -> {
            if (openApi.getTags()!=null){
                openApi.getTags().forEach(tag -> {
                    Map<String,Object> map=new HashMap<>();
                    map.put("x-order", new Random().nextInt(0,100));
                    tag.setExtensions(map);
                });
            }
            if(openApi.getPaths()!=null){
                openApi.addExtension("x-test123","333");
                openApi.getPaths().addExtension("x-abb",new Random().nextInt(1,100));
            }

        };
    }

    @Bean
    public OpenAPI customOpenAPI() {
        Info info = new Info();
        Contact contact = new Contact();
        contact.setName("zhangjg");
        contact.setUrl("http://localhost:"+port);
        contact.setEmail("zhangjg@gmail.com");
        info.setContact(contact);
        return new OpenAPI()
                .info(info
                        .title("用户应用程序接口文档")
                        .version("1.0")
                        .description( "用户服务")
                        .termsOfService("http://doc.xiaominfo.com")
                        .license(new License().name("Apache 2.0")
                                .url("http://doc.xiaominfo.com")));
    }
}

1.3 控制器

package org.example.user.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.example.common.model.Result;
import org.example.common.util.JwtUtils;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Create by zjg on 2024/7/21
 */
@Tag(name = "用户模块")
@RestController
@RequestMapping("/user/")
public class UserController {
    List<String> users = List.of("admin");
    @Operation(summary = "用户是否存在")
    @RequestMapping("exist")
    public Boolean exist(@RequestParam("username") String username){
        boolean exist=false;
        if(users.contains(username)){
           exist=true;
        }
        return exist;
    }
    @Operation(summary = "用户登录")
    @RequestMapping("login")
    public Result<String> login(@RequestParam("username") String username, @RequestParam("password") String password){
        String message="用户名/密码不正确";
        String admin="admin";
        if(admin.equals(username)&&admin.equals(password)){
            Map<String, Object> claims=new HashMap<>();
            claims.put("username",username);
            return new Result<>(HttpStatus.OK.value(), "请求成功",JwtUtils.create(claims));
        }
        return Result.error(HttpStatus.UNAUTHORIZED.value(), message);
    }
}

2. 网关服务

现在是这么一个场景:用户服务太重要了,他们也要接入网关文档服务中,但是系统server.servlet.context-path配置还不能改,这么说大家可能不明白,直接看url区别吧
用户服务:http://localhost:9007/v3/api-docs
网关服务:http://localhost:9007/user/v3/api-docs

方案1
用户服务添加server.servlet.context-path=user,但是如果你的系统已经有很多内容了,不建议改,它的影响范围是ALL,会影响用户系统的所有请求。
方案2
用户服务添加接口/user/v3/api-docs,接收到请求之后,获取本机http://localhost:9007/v3/api-docs并将响应返回,相当于中转了一层
方案3 推荐 \color{#00FF00}{推荐} 推荐
其实我们的网关是很灵活的,这时候就需要网关层做动作适应它,先讲下思路:

  1. 排除的微服务user-serviceknife4j配置
  2. 定义新的路由和新的断言规则,指向user-service
  3. 手动配置user-service,聚合默认分组

2.1 排除用户服务

knife4j:
  gateway:
    # ① 第一个配置,开启gateway聚合组件
    enabled: true
    # ② 第二行配置,设置聚合模式采用discover服务发现的模式
    strategy: discover
    discover:
      # ③ 第三行配置,开启discover模式
      enabled: true
      # ④ 第四行配置,聚合子服务全部为OpenAPI3规范的文档
      version: openapi3
      # 需要排除的微服务(eg:网关服务) 
      excluded-services:
        - user-service

2.2 定义新用户服务路由

定义路由user-service1,并将请求http://localhost:9007/user/v3/api-docs去掉一层前缀,真实请求为http://localhost:9007/v3/api-docs,完美解决

spring:
  cloud:
    gateway:
      httpclient:
        connect-timeout: 1000
        response-timeout: 5s
      routes:
      - id: provider-service
        uri: lb://provider-service
        predicates:
        - Path=/provider/**
        - BlackRemoteAddr=192.168.1.1/24,127.0.0.1,192.168.0.104
      - id: consumer-service
        uri: lb://consumer-service
        predicates:
        - Path=/consumer/**,/echo-rest/**,/echo-feign/**
        filters:
        - BlackList=/consumer/hello1,/consumer/hello2
        metadata:
          optionName: "OptionValue"
          compositeObject:
            name: "value"
          iAmNumber: 1
          connect-timeout: 200
          response-timeout: 6000
      - id: user-service
        uri: lb://user-service
        predicates:
        - Path=/user/**
      - id: user-service1
        uri: lb://user-service
        predicates:
        - Path=/user-service/**
        filters:
        - StripPrefix=1

2.3 手动聚合分组

我们在knife4j.gateway下定义一套routes匹配我们刚才的路由即可

knife4j:
  gateway:
    # ① 第一个配置,开启gateway聚合组件
    enabled: true
    # ② 第二行配置,设置聚合模式采用discover服务发现的模式
    strategy: discover
    discover:
      # ③ 第三行配置,开启discover模式
      enabled: true
      # ④ 第四行配置,聚合子服务全部为OpenAPI3规范的文档
      version: openapi3
      # 需要排除的微服务(eg:网关服务) 
      excluded-services:
        - user-service
    # 子服务存在其他分组情况,聚合其他分组,只能手动配置
    routes:
      - name: 用户服务
        # 子服务存在其他分组情况,聚合其他分组
        url: /user-service/v3/api-docs?group=default
        # 服务名称(Optional)
        service-name: user-service
        # 路由前缀
        context-path: /
        # 排序
        order: 1
    basic:
      enable: true
      # Basic认证用户名
      username: admin
      # Basic认证密码
      password: admin

3. 效果展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


总结

回到顶部

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

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

相关文章

JG08Z-GD系列 八轴智能测径仪系统介绍

1.测径仪&#xff1a; 主要用于轧制线&#xff0c;棒材&#xff0c;八个方向直径及椭圆度在线测量&#xff0c;轧制螺纹钢特钢尺寸在线测量。 2.功能介绍&#xff1a; &#xff08;1&#xff09;显示内容 主控室液晶显示器&#xff1a;管材截面的最大/最小直径、平均值、椭圆…

问题本记录(1):mac有网络但打不开网页

此学习类别&#xff0c;仅作为小许的问题本&#xff0c;方便后续再次遇到相关问题进行查看。 第一步&#xff1a; 第二步&#xff1a; 添加一个新的位置 第三步&#xff1a; 选择这个新建的位置&#xff0c;Wi-Fi显示已连接就 万事大吉啦啦啦

html+css+js+jquery实现一个 飘零的树叶

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>飘落的枫叶</title><style>.maple {position: absolute;top: 0;color: #ff0000;}</style><script src"https://www.jq22.com…

片上POR和BOR的区别

片上 POR 和 BOR 的区别 片上 POR&#xff08;Power On Reset&#xff09;和 BOR&#xff08;Brown-out Reset&#xff09;是微控制器中用于确保系统在电源异常情况下能够恢复正常运作的两种复位机制。 1. POR&#xff08;上电复位&#xff09; POR 是在微控制器上电时触发的…

多路RTSP转RTMP推送方案的两个选择

技术选型 RTSP转RTMP推送到流媒体服务器&#xff0c;说起来技术实现不难&#xff0c;简单来说&#xff0c;获取RTSP流后&#xff0c;拿到未经解码的H.264/H.265和audio数据&#xff0c;重新打包RTMP发送出去即可。需要注意的是&#xff0c;大多RTSP转RTMP模块&#xff0c;需要…

数学建模~~追逐仿真问题

目录 1.前景介绍 2.题目描述 3.核心思路 4.思路分析 5.代码分析 5.1准备工作 5.2设置循环 5.3终止循环 5.4绘制图形 5.5完整代码 1.前景介绍 今天上午的数学建模培训王老师介绍的这个数学建模相关的经验真的是让我受益匪浅&#xff0c;让我对于数学建模有了更加清晰的…

数据增强库albumentations使用指南

数据增强技术就是人为地生成真实数据集的不同版本以增加其数据大小。计算机视觉(CV)和自然语言处理 (NLP) 在模型训练过程中经常使用数据增强策略来处理数据稀缺和数据多样性不足的问题&#xff0c;避免模型因数据量而导致的过拟合、泛化性不足等问题。计算机视觉中常见的数据增…

Node.JS - 基础

目录 A. 简介 B. 安装和配置 C. npm A. 简介 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 一、运行原理 事件驱动和非阻塞 I/O 模型&#xff1a; Node.js 采用事件驱动、异步编程的方式。这意味着它不会在等待一个操作&#xff08;如读取文件或网络请求&a…

spfa算法判断是否存在负权回路

spfa算法判断是否存在负权回路 题目 当一个图中存在一个负权回路时&#xff0c;是无法利用spfa 算法去求最短路问题的&#xff0c;但是可以利用spfa 算法判断有没有负权回路 题目 给定一个 n n n 个点 m m m 条边的有向图&#xff0c;图中可能存在重边和自环&#xff0c; 边…

VisionPro二次开发学习笔记11-使用 Caliper和Fixture定位Blob工具检测方块

该示例演示了如何使用卡尺工具和夹具工具来固定 Blob 工具。示例代码将检测图像上部区域中小方块的存在。当点击“运行”按钮时&#xff0c;将读取一张新图像。卡尺工具将被运行&#xff0c;卡尺工具的输出 Y 信息将传递给夹具工具。夹具工具使用来自卡尺工具的 Y 信息和新图像…

新手养猫怎么选智能猫砂盆?不踩雷平价实用攻略测评分享!

众所周知&#xff0c;猫咪是非常爱干净的动物&#xff0c;一旦猫砂盆满了&#xff0c;它们就可能会选择其他角落“解决”&#xff0c;这不仅会让家里充满异味&#xff0c;还可能影响猫咪的健康。而长期堆积的猫砂&#xff0c;也容易滋生细菌&#xff0c;对猫咪的爪子也是一种伤…

[CISCN2019 华东南赛区]Web111

打开题目&#xff0c;看到题目 注意最下面的Build With Smarty! , 猜测是smarty模板注入。smart是php的模板引擎&#xff0c;模板引擎的作用就是分离前端页面和数据的&#xff0c;题目中显示API的URL由于环境的原因无法使用&#xff0c;但我们的IP依旧显示在了页面的右上角&…

python-约瑟夫环(赛氪OJ)

[题目描述] n 个人&#xff08; 0,1,2,3,4...n−1 &#xff09;&#xff0c;围成一圈&#xff0c;从编号为 k 的人开始报数&#xff0c;报数报到 m 的人出队。 下次从出队的人之后开始重新报数&#xff0c;循环往复&#xff0c;当队伍中只剩最后一个人的时候&#xff0c;那个人…

【Material-UI】Checkbox 组件中的 Label Placement 设置详解

文章目录 一、Checkbox 组件简介1. 组件概述2. labelPlacement 属性 二、labelPlacement 属性的使用方法三、各标签位置的效果与应用场景1. Top&#xff08;顶部&#xff09;2. Start&#xff08;左侧&#xff09;3. Bottom&#xff08;底部&#xff09;4. End&#xff08;右侧…

【文献精读】LOCA 图4

&#xff08;1&#xff09;数据流动 QKV的选取

Compass Arena 上新啦!新增双多模态模型匿名对战

2024 年 5 月&#xff0c;上海人工智能实验室司南 OpenCompass 团队 与魔搭 ModelScope 联合推出了大模型评测平台——Compass Arena&#xff08;大模型竞技场&#xff09;&#xff0c;为国内的大语言模型领域引入了一种全新的竞技模式。 今天&#xff0c;Compass Arena 迎来重…

JVM知识总结(G1收集器)

文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ G1收集器 G1**&#xff08;Garbage First&#xff09;是一款面向服…

Mocaverse「Enter MOCALAND」上线!

我们很高兴宣布 Mocaverse 和 The Sandbox 将开展一项新合作——「Enter MOCALAND&#xff01;」 继 “Into the Unknow” Game Jam 成功举办之后&#xff0c;我们的创作者们在此基础上创作出了近 50 款未来派多人游戏&#xff0c;我们很高兴能继续与社区一起庆祝共同创作&…

Redis与DataBase保持数据一致性

文章目录 1. 读取数据2. 写数据2.1 先操作缓存2.2 先操作数据库 在我们系统中缓存最常用的策略是&#xff1a;服务端需要同时维系DB和Cache&#xff0c;并且是以DB的结果为准&#xff0c; Cache-Aside Pattern&#xff08;缓存分离模式、旁路缓存&#xff09;。 1. 读取数据 当…

高质量翻译对中国移动应用在国外市场推广的影响

在移动应用的竞争格局中&#xff0c;打入国外市场对中国开发商来说既是机遇也是挑战。决定中国移动应用程序在海外成功的最关键因素之一是其翻译质量。高质量的翻译在有效推广该应用程序、确保其与当地用户产生共鸣&#xff0c;并最终推动新市场的采用和增长方面发挥着关键作用…