设计模式-过滤器模式(使用案例)

        过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准。

        业务场景:每次请求通过网关,需要验证请求头是否携带 token,sign签名等

        类图:

AuthService:所有滤器类都必须实现的接口

AuthTokenServiceImpl:Token验证过滤器

AuthSignServiceImpl:签名验证过滤器

AuthFactory:过滤器工厂,利用SpringBoot功能特性,实现自动获取过滤器

AuthDTO:过滤器所需要的参数

AuthGatewayFilterFactory:权限校验过滤器(gateway)

AuthService:

/*** @Author: wmh* @Description: 权限校验过滤器* @Date: 2023/8/3 18:19* @Version: 1.0*/
public interface AuthService {/*** @Description: 过滤方法* @Param authDTO: 网关上下文* @return: String* @Author: wmh* @Date: 2023/8/3 18:12*/String apply(AuthDTO authDTO);}

返回值可以定义为统一返回值(R)等,为了演示方便,就返回字符串了

AuthTokenServiceImpl:

import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;/*** @Author: wmh* @Description: token校验* @Date: 2023/8/3 18:21* @Version: 1.0*/
@Slf4j
@Order(0)
@Service
public class AuthTokenServiceImpl implements AuthService {/*** @Description: 验证token* @Param authDTO: 网关上下文* @return: com.norinaviation.atm.common.base.data.R* @Author: wmh* @Date: 2023/8/3 19:31*/@Override@SneakyThrowspublic String apply(AuthDTO authDTO) {String tokenHeader = authDTO.getHeaders().getFirst(CommonConstant.X_TOKEN);if (StrUtil.isBlank(appId)) {return "appId不能为空";}if (StrUtil.isBlank(tokenHeader)) {return "TOKEN不能为空";}JWT jwt = JWTUtil.parseToken(tokenHeader);boolean verifyKey = jwt.setKey(CommonConstant.JWT_TOKEN.getBytes()).verify();// 验证token是否正确if (!verifyKey) {log.info("appId:{}, TOKEN auth fail, TOKEN:{}", appId, tokenHeader);return "TOKEN认证失败";}boolean verifyTime = jwt.validate(0);// 验证token是否过期if (!verifyTime) {log.info("appId:{}, TOKEN expired, TOKEN:{}", appId, tokenHeader);return "TOKEN已过期";}return "success";}}

AuthSignServiceImpl:

import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
/*** @Author: wmh* @Description: 验签校验* @Date: 2023/8/3 18:24* @Version: 1.0*/
@Slf4j
@Order(1)
@Service
public class AuthSignServiceImpl implements AuthService {/*** @Description: 验证签名* @Param authDTO: 网关上下文* @return: Stirng* @Author: wmh* @Date: 2023/8/3 19:30*/@Override@SneakyThrowspublic Stirng apply(AuthDTO authDTO) {// 签名逻辑,业务代码就不公开了return "success";}}

AuthFactory:

import cn.hutool.core.util.ObjectUtil;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;import java.util.*;/*** @Author: wmh* @Description: 权限工厂* @Date: 2023/8/7 15:54* @Version: 1.0*/
@Component
public class AuthFactory implements ApplicationContextAware {/*** 过滤方式*/private List<AuthService> authFilters = new ArrayList<>();/*** 获取应用上下文并获取相应的接口实现类* @param applicationContext* @throws BeansException*/@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {// 获取实现类Map<Integer, AuthService> authServiceMap = new HashMap<>();applicationContext.getBeansOfType(AuthService.class).values().stream().forEach(authService -> {if (ObjectUtil.isNull(authService.getClass().getAnnotation(Order.class))) {authServiceMap.put(CommonConstant.DEFAULT_ORDER, authService);}else {authServiceMap.put(authService.getClass().getAnnotation(Order.class).value(), authService);}});// 根据order排序authServiceMap.entrySet().stream().sorted(Comparator.comparing(e -> e.getKey())).forEach(map -> {authFilters.add(map.getValue());});}/*** @Description: 是否全部符合过滤条件* @Param authDTO: 网关上下文* @return: String* @Author: wmh* @Date: 2023/8/3 19:27*/public String apply(AuthDTO authDTO) {for (AuthService filter : authFilters) {String str = filter.apply(authDTO);if (!StrUtil.equals(str, "success")) {return str;}}return "success";}}

AuthDTO:

import lombok.Data;
import org.springframework.http.HttpHeaders;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;/*** @Author: wmh* @Description: 网关上下文* @Date: 2023/8/3 19:09* @Version: 1.0*/
@Data
public class AuthDTO {/*** cache headers*/private HttpHeaders headers;/*** cache json body*/private String cacheBody;/*** cache formdata*/private MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();}

此类为gateway网关需要,只展示使用过滤链的代码块

AuthGatewayFilterFactory:

/*** @Author: wmh* @Description: 权限校验过滤器* @Date: 2023/8/3 19:15* @Version: 1.0*/
@Slf4j
@Component
public class AuthGatewayFilterFactory extends AbstractGatewayFilterFactory {@Autowiredprivate AuthFactory authFactory;@Overridepublic GatewayFilter apply(Config config) {return (exchange, chain) -> {ServerHttpRequest serverHttpRequest = exchange.getRequest();...// 获取request bodyGatewayContext gatewayContext = exchange.getAttribute(GatewayContext.CACHE_GATEWAY_CONTEXT);AuthDTO authDTO = new AuthDTO();authDTO.setHeaders(gatewayContext.getHeaders());authDTO.setCacheBody(gatewayContext.getCacheBody());authDTO.setFormData(gatewayContext.getFormData());// 验证String strr = authFactory.apply(authDTO);...return chain.filter(exchange);};}}

Gateway相关:SpringCloud-Gateway实现网关_springcloud配置网关_W_Meng_H的博客-CSDN博客网关作为流量的入口,常用的功能包括路由转发、权限校验、限流等Spring Cloud 是Spring官方推出的第二代网关框架,由WebFlux+Netty+Reactor实现的响应式的API网关,它不能在传统的servlet容器工作,也不能构建war包。基于Filter的方式提供网关的基本功能,例如说安全认证、监控、限流等。_springcloud配置网关https://blog.csdn.net/W_Meng_H/article/details/129775851

CommonConstant(常量类):

/*** @Author: wmh* @Description: 常用变量* @Date: 2023/3/30 10:29* @Version: 1.0*/
@Component
public class CommonConstant {// JWT密钥public static String JWT_TOKEN;// 请求头中的tokenpublic static final String X_TOKEN = "X-TOKEN";// 请求头中的签名public static final String X_SIGN = "X-SIGN";// 请求头中的appIdpublic static final String X_APPID = "X-APPID";// 请求头中的时间戳public static final String X_TIMESTAMP = "X-TIMESTAMP";}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Azure使用CLI创建VM

使用CLI创建VM之前&#xff0c;确保资源中的IP资源已经释放掉了&#xff0c;避免创建的过程中没有可以利用的公共IP地址打开 cloudshell ,并输入创建CLI的命令如下&#xff0c;-n指定名称&#xff0c;-g指定资源组&#xff0c;image指定镜像&#xff0c;admin-usernam指定用户名…

如何快速制作解决方案PPT

如何快速制作解决方案PPT 理解客户的需求 在开始制作解决方案PPT之前&#xff0c;需要对客户的需求进行深入了解和分析。这包括客户需要解决的问题、目标、预算和时间限制等。 需求分析 客户需要解决的问题客户的目标预算限制时间限制 确定解决方案 基于客户的需求&#x…

发布一个开源的新闻api(整理后就开源)

目录 说明: 基础说明 其他说明: 通用接口&#xff1a; 登录: 注册: 更改密码(需要token) 更换头像(需要token) 获取用户列表(需要token): 上传文件(5000端口): 获取文件(5000端口)源码文件&#xff0c;db文件均不能获取: 验证token(需要token): 获取系统时间: 文件…

VMware 虚拟机三种网络模式详解

文章目录 前言桥接模式(Bridged)桥接模式特点: 仅主机模式 (Host-only)仅主机模式 (Host-only)特点: NAT网络地址转换模式(NAT)仅主机模式 (Host-only)特点: 前言 很多同学在初次接触虚拟机的时候对 VMware 产品的三种网络模式不是很理解,本文就 VMware 的三种网络模式进行说明…

GBU816-ASEMI新能源专用整流桥GBU816

编辑&#xff1a;ll GBU816-ASEMI新能源专用整流桥GBU816 型号&#xff1a;GBU816 品牌&#xff1a;ASEMI 封装&#xff1a;GBU-4 恢复时间&#xff1a;&#xff1e;50ns 正向电流&#xff1a;8A 反向耐压&#xff1a;1600V 芯片个数&#xff1a;4 引脚数量&#xff1…

判断平面中两射线是否相交的高效方法

1. 简介 最近在工作中遇到判断平面内两射线是否相交的问题。 对于这个问题的解决,常规的方法是将两条射线拓展为直线,计算直线的交点,而后判断交点是否在射线上。 这种方法,在思路上较为直观,也易于理解。然后,该方法在计算量上相对较大。对于少量射线间的交点计算尚可…

一、docker及mysql基本语法

文章目录 一、docker相关命令二、mysql相关命令 一、docker相关命令 &#xff08;1&#xff09;拉取镜像&#xff1a;docker pull <镜像ID/image> &#xff08;2&#xff09;查看当前docker中的镜像&#xff1a;docker images &#xff08;3&#xff09;删除镜像&#x…

如何将图片应用于所有的PPT页面?

问题&#xff1a;如何快速将图片应用到所有PPT页面&#xff1f; 解答&#xff1a;有两种方法可以解决这个问题。第一种用母板。第二种用PPT背景功能。 解决有时候汇报的时候&#xff0c;ppt中背景图片修改不了以及不知道如何查找&#xff0c;今天按照逆向过程进行操作 方法1…

C# 观察者模式

一、概述 观察者模式是一种常用的设计模式&#xff0c;它属于行为型模式。在C#中&#xff0c;观察者模式通过定义一种一对多的依赖关系&#xff0c;使得当一个对象的状态发生变化时&#xff0c;所有依赖于它的对象都会得到通知并自动更新。这种模式可以实现松耦合&#xff0c;…

k8s 自身原理之 Service

好不容易&#xff0c;终于来到 k8s 自身的原理之 关于 Service 的一部分了 前面我们用 2 个简图展示了 pod 之间和 pod 与 node 之间是如何通信息的&#xff0c;且通信的数据包是不会经过 NAT 网络地址转换的 那么 Service 又是如何实现呢&#xff1f; Service 我们知道是用…

常见的 Python 错误及其解决方案

此文整理了一些常见的 Python 错误及其解决方案。 1、SyntaxError: invalid syntax 说明&#xff1a;无效的语法是最常见的错误之一&#xff0c;通常是由于编写代码时违反了 Python 的语法规则。可能的原因&#xff1a; 忘记在 if、while、for 等语句后写冒号&#xff0c;或者…

VS2015打开Qt的pro项目文件 报错

QT报错&#xff1a;Project ERROR: msvc-version.conf loaded but QMAKE_MSC_VER isn‘t set 解决方法&#xff1a; 找到本机安装的QT路径&#xff0c;找到“msvc-version.conf”文件&#xff0c;用记事本打开&#xff0c; 在其中添加版本“QMAKE_MSC_VER 1900”保存即可。 …

基于VUE3+Layui从头搭建通用后台管理系统(前端篇)八:自定义组件封装上

一、本章内容 本章实现一些自定义组件的封装,包括数据字典组件的封装、下拉列表组件封装、复选框单选框组件封装、单选框组件封装、文件上传组件封装、级联选择组件封装、富文本组件封装等。 1. 详细课程地址: 待发布 2. 源码下载地址: 待发布 二、界面预览 ![在这里插入图…

无人机跟随一维高度避障场景--逻辑分析

无人机跟随一维高度避障场景--逻辑分析 1. 源由2. 视频3. 问题3.1 思维发散3.2 问题收敛 4. 图示4.1 水平模式4.2 下坡模式4.3 上坡模式4.4 碰撞分析 5. 总结5.1 一维高度避障场景5.2 业界跟随产品5.3 APM集成跟随示意图一&#xff1a;示意图二&#xff1a;示意图三&#xff1a…

Azure防火墙

文章目录 什么是Azure防火墙如何部署和配置创建虚拟网络创建虚拟机创建防火墙创建路由表&#xff0c;关联子网、路由配置防火墙策略配置应用程序规则配置网络规则配置 DNAT 规则 更改 Srv-Work 网络接口的主要和辅助 DNS 地址测试防火墙 什么是Azure防火墙 Azure防火墙是一种用…

XenDesktop5.6如何连接数据库

Citrix在数据库的连接方式上一直不统一&#xff0c;但是也还是有迹可循的。 经过了好长时间的下载以后&#xff0c;今天终于有时间来测试一下最新版本的XenDesktop 5 SP1&#xff0c;由于结合了其他组件和环境的需要&#xff0c;所以&#xff0c;选择了独立部署数据库&#xf…

clickhouse-监控配置

一、概述 监控是运维的一大利器&#xff0c;要想运维好clickhouse,首先就要对其进行监控&#xff0c;clickhouse有几种监控数据的方式&#xff0c;一种是系统本身监控&#xff0c;一种是通过exporter来监控&#xff0c;下面分别描述一下 二、系统自带监控 我下面会对监控做一…

Jenkins-发送邮件配置

在Jenkins构建执行完毕后&#xff0c;需要及时通知相关人员。因此在jenkins中是可以通过邮件通知的。 一、Jenkins自带的邮件通知功能 找到manage Jenkins->Configure System&#xff0c;进行邮件配置&#xff1a; 2. 配置Jenkins自带的邮箱信息 完成上面的配置后&#xf…

08 - 网络通信优化之IO模型:如何解决高并发下IO瓶颈?

提到 Java I/O&#xff0c;相信你一定不陌生。你可能使用 I/O 操作读写文件&#xff0c;也可能使用它实现 Socket 的信息传输…这些都是我们在系统中最常遇到的和 I/O 有关的操作。 我们都知道&#xff0c;I/O 的速度要比内存速度慢&#xff0c;尤其是在现在这个大数据时代背景…

排序算法-冒泡排序(C语言实现)

简介&#x1f600; 冒泡排序是一种简单但效率较低的排序算法。它重复地扫描待排序元素列表&#xff0c;比较相邻的两个元素&#xff0c;并将顺序错误的元素交换位置&#xff0c;直到整个列表排序完成。 实现&#x1f9d0; 以下内容为本人原创&#xff0c;经过自己整理得出&am…