Gateway集成方法以及拦截器和过滤器的使用

前提:请先创建好一个SpringBoot项目 

1. 引入依赖

 SpringCloud 和 alibabaCloud 、 SpringBoot间对版本有强制要求,我使用的springboot是3.0.2的版本。版本对应关系请看:版本说明 · alibaba/spring-cloud-alibaba Wiki · GitHub

    <dependencyManagement><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>2022.0.3</version></dependency></dependencyManagement><dependencies><!-- SpringCloud组件之一,不加会提示错误 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-loadbalancer</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId><version>3.1.4</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency></dependencies>

2. 搭建网关

配置bootstrap.yml文件:

server:port: 8083
spring:application:name: big-news-admin-gatewaycloud:nacos:discovery:server-addr: 你的ip:8848config:server-addr: 你的ip:8848file-extension: yml

 Nacos配置中心:

yml示例:

spring:data:redis:host: localhostport: 6379cloud:gateway:globalcors:add-to-simple-url-handler-mapping: truecorsConfigurations:'[/**]':allowedHeaders: "*"allowedOrigins: "*"allowedMethods:- GET- POST- DELETE- PUT- OPTIONroutes:# 平台管理- id: useruri: lb://big-news-userpredicates:- Path=/user/**# 分类- id: categoryuri: lb://big-news-categorypredicates:- Path=/category/**# 文章- id: articleuri: lb://big-news-articlepredicates:- Path=/article/**# 文件- id: commonuri: lb://big-news-commonpredicates:- Path=/upload/**
token:secretKey: rikka7e7f74ef-62b5-4b29-96ae-c698f7c823c1expirationTime: 1080000060

解释:

该配置用于解决跨域问题

路由断言规则,id需唯一,uri中的名称需要对应服务的应用名。path用于匹配路由。

以下图举例:uri意味着将请求匹配到nacos中名叫big-news-user的服务,path意味着根据只要请求携带`user`就匹配服务。

可用 filters 过滤掉请求中的字段,比如下图。意味着最后到服务的实际请求不会携带`user`,你就不需要在controller的接收路径上上写`user`。

 3. 全局过滤器实现jwt校验

思路分析:

  1. 用户进入网关开始登陆,网关过滤器进行判断,如果是登录,则路由到后台管理微服务进行登录

  2. 用户登录成功,后台管理微服务签发JWT TOKEN信息返回给用户

  3. 用户再次进入网关开始访问,网关过滤器接收用户携带的TOKEN

  4. 网关过滤器解析TOKEN ,判断是否有权限,如果有,则放行,如果没有则返回未认证错误  

 3.1 拷贝一份jwt工具类到网关服务

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;@Component
public class JwtUtil {private static final String USER_CLAIMS_KEY = "user";// 过期时间@Value("${token.expirationTime}")private long EXPIRE_TIME;// 密钥@Value("${token.secretKey}")private String SECRET;/*** 创建JWT Token** @param payload 载荷(Claims)* @return JWT Token*/public String createToken(Map<String, Object> payload) {// 1. 创建一个密钥SecretKey key = Keys.hmacShaKeyFor(SECRET.getBytes(StandardCharsets.UTF_8));// 2. 创建JWT Builder// 注意:这里的签名算法不能是 RS256,需要使用 HS256io.jsonwebtoken.JwtBuilder builder = Jwts.builder().setClaims(payload).setExpiration(new Date(System.currentTimeMillis() + EXPIRE_TIME)).signWith(key, SignatureAlgorithm.HS256);// 3. 生成JWT Tokenreturn builder.compact();}/*** 解析JWT Token** @param token JWT Token* @return 载荷(Claims)*/public Map<String, Object> parseToken(String token) {// 1. 获取密钥SecretKey key = Keys.hmacShaKeyFor(SECRET.getBytes(StandardCharsets.UTF_8));// 2. 解析JWT TokenClaims claims = Jwts.parser().setSigningKey(key).build().parseClaimsJws(token).getBody();// 3. 将Claims里的内容转换成MapMap<String, Object> payload = new HashMap<>(claims);payload.remove("exp");payload.remove("iat");payload.remove("iss");payload.remove("aud");payload.remove("nbf");payload.remove("sub");payload.remove("jti");return payload;}/*** 获取JWT Token的过期时间** @param token JWT Token* @return 过期时间*/public Date getExpirationDateFromToken(String token) {Claims claims = parseClaims(token);if (claims != null) {return claims.getExpiration();}return null;}/*** 验证JWT Token是否有效** @param token JWT Token* @return 是否有效*/public boolean validateToken(String token) {try {parseClaims(token);return true;} catch (Exception e) {return false;}}/*** 获取payload中的用户信息** @param token JWT Token* @return 用户信息*/public Map<String, Object> getUserFromToken(String token) {Map<String, Object> user = null;Claims claims = parseClaims(token);if (claims != null) {user = (Map<String, Object>) claims.get(USER_CLAIMS_KEY);}return user;}/*** 解析JWT Token中的Claims** @param token JWT Token* @return Claims*/public Claims parseClaims(String token) {try {SecretKey key = Keys.hmacShaKeyFor(SECRET.getBytes(StandardCharsets.UTF_8));return Jwts.parser().setSigningKey(key).build().parseClaimsJws(token).getBody();} catch (Exception e) {return null;}}}

 3.2 网关微服务中新建全局过滤器

import cn.hutool.json.JSONUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.xin.common.properties.TokenProperties;
import com.xin.common.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import java.util.Objects;@Component
public class AuthorizeFilter implements Ordered, GlobalFilter {@Autowiredprivate StringRedisTemplate stringRedisTemplate;//用于接收token的信息,你可按实际请看书写,也可以直接在这个类里定义静态参数。//tokenProperties主要包含:密钥key、过期时间@Autowiredprivate TokenProperties tokenProperties;@Autowiredprivate JwtUtil jwtUtil;@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//1.获取请求ServerHttpRequest request = exchange.getRequest();ServerHttpResponse response = exchange.getResponse();//2.判断是否是登录操作if (request.getURI().getPath().contains("/login")) {//放行return chain.filter(exchange);}String token = request.getHeaders().getFirst("Authorization");//3.若token为空,校验失败if (StringUtils.isEmpty(token)){response.setStatusCode(HttpStatus.UNAUTHORIZED);//结束请求return response.setComplete();}try {//4. 解析tokenClaims claims = jwtUtil.parseClaims(token);//获得token解析后中的用户信息Object o = claims.get("user");String user = JSONUtil.toJsonStr(o);String id = user.substring(user.indexOf(":")+1, user.indexOf(","));//5.判断token是否在redis中过期,或删除String object = stringRedisTemplate.opsForValue().get("token:" + id + ":" + token);if (Objects.isNull(object)) {response.setStatusCode(HttpStatus.UNAUTHORIZED);//结束请求return response.setComplete();}// 将用户信息存放进 header中ServerHttpRequest serverHttpRequest = request.mutate().headers(httpHeaders -> {httpHeaders.add("user", user + "");}).build();exchange.mutate().request(serverHttpRequest).build();}catch (Exception e){e.printStackTrace();response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}//5.放行return chain.filter(exchange);}/*** 优先级设置,值越小 优先级越高* @return*/@Overridepublic int getOrder() {return 0;}
}

注意,该过滤器只是实现了对Token的校验,并将解析结果存放进header进一步转发。获取user信息,还需在实际的服务里定义拦截器获取:

@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String userString = request.getHeader("user");Optional<String> optional = Optional.ofNullable(userString);if(optional.isPresent()) {//把用户存入threadLocal中TreadLocalUtil.setUser(userString);log.info("设置用户信息到threadlocal中...");}return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {TreadLocalUtil.clear();log.info("清理threadlocal...");}
}

 在WebMvcConfig中配置该拦截器:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**");}
}

最后最后!!!各位看官觉得有用就收藏、点赞、评论一下吧。我看到问题后,我会第一时间回复的! ​​​​​​​ 

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

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

相关文章

(windows2012共享文件夹和防火墙设置

windows2012共享文件夹和防火墙设置 1.windows2012文件夹共享1.共享和高级共享的区别![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/0d815cc6862a4c7a99be11442fb5d950.png#pic_center) 2.windows的防火墙设置1.防火墙设置8080端口让tomot可以在主机可以访问1.新建…

中间件系列 - Redis入门到实战(高级篇-最佳实践)

前言 学习视频&#xff1a; 黑马程序员Redis入门到实战教程&#xff0c;深度透析redis底层原理redis分布式锁企业解决方案黑马点评实战项目中间件系列 - Redis入门到实战本内容仅用于个人学习笔记&#xff0c;如有侵扰&#xff0c;联系删除学习目标 Redis键值设计批处理优化服…

电商数据分析-03-电商数据采集

参考 最最最全数据仓库建设指南&#xff0c;速速收藏&#xff01;&#xff01; 第1章 数据仓库概念 数据仓库规划 1.1 数仓搭建 我们这里所说的数据仓库&#xff0c;是基于大数据体系的&#xff0c;里面包含标签类目&#xff0c;区别于传统的数据仓库。下面我们来将这张图分解…

STM32 支持IAP的bootloader开发,使用串口通过Ymodem协议传输固件

资料下载: https://download.csdn.net/download/vvoennvv/88658447 一、概述 关于IAP的原理和Ymodem协议&#xff0c;本文不做任何论述&#xff0c;本文只论述bootloader如何使用串口通过Ymodem协议接收升级程序并进行IAP升级&#xff0c;以及bootloader和主程序两个工程的配置…

dxbuilder关于开发一款国产数据库建模软件的思考与行动

一、背景 随着一声紧急的呼叫&#xff0c;快快快。把你们有安装PownerDesigner的软件都卸载掉&#xff0c;公司被发律师函了&#xff0c;这是来自于领导的呼喊。 我们公司大部分的软件的数据结构&#xff0c;都是用PownerDesigner来进行设计的。以便进行后期的管理与维护。不…

Vue学习之第一、二章——Vue核心与组件化编程

第一章. Vue核心 1.1 Vue简介 1.1.1 官网 英文官网: https://vuejs.org/中文官网: https://cn.vuejs.org/ 1.1.2 Vue特点 遵循 MVVM 模式编码简洁, 体积小, 运行效率高, 适合移动/PC 端开发它本身只关注 UI, 也可以引入其它第三方库开发项目 1.2 初始Vue 这里可以参考&a…

ios 之 数据库、地理位置、应用内跳转、推送、制作静态库、CoreData

第一节&#xff1a;数据库 常见的API SQLite提供了一系列的API函数&#xff0c;用于执行各种数据库相关的操作。以下是一些常用的SQLite API函数及其简要说明&#xff1a;1. sqlite3_initialize:- 初始化SQLite库。通常在开始使用SQLite之前调用&#xff0c;但如果没有调用&a…

“京东”数据包暴雷——李逵还是李鬼?

大家好&#xff0c;我是吴军&#xff0c;一家软件技术开发公司的产品经理。 前几个月市面上出现了一个京东数据包的项目&#xff0c;乍一听还蛮正规的&#xff0c;强子不卖货&#xff0c;去做数据服务了&#xff1f;他究竟是怎么一个盈利方式&#xff1f;到底是李逵还是李鬼&a…

【新资讯】《网络安全事件报告管理办法(征求意见稿)》正在公开征求意见

近年来网络安全事故频发&#xff0c;造成了不少损失和危害。为了减少网络安全事故的发生&#xff0c;规范网络安全事件的报告&#xff0c;国家互联网信息办公室根据《中华人民共和国网络安全法》等法律法规起草了《网络安全事件报告管理办法&#xff08;征求意见稿&#xff09;…

释放创意,点亮视频!红巨星Magic Bullet Looks带给您绚丽的色彩魔法

Red Giant Magic Bullet Looks 是一款适用于Mac的视频后期处理软件。它是由Red Giant公司开发的一款专业级颜色校正和调色工具&#xff0c;旨在帮助电影制作人、视频编辑和摄影师实现令人惊叹的视觉效果。 Magic Bullet Looks 提供了一个直观而强大的用户界面&#xff0c;使用…

Linux操作系统(Crontab计划任务+NTP时间同步服务器)

如何修改linux系统时间 与时间相关的命令&#xff0c;查看当前的时间 运行 date 即可 cal 查看当前月份的日历 运行 timedatectl 查看时间详细参数 &#xff08; NTP&#xff1a; network time protocol 网络时间协议 &#xff09; &#xff08; local time : 本地时间 &#x…

大创项目推荐 深度学习LSTM新冠数据预测

文章目录 0 前言1 课题简介2 预测算法2.1 Logistic回归模型2.2 基于动力学SEIR模型改进的SEITR模型2.3 LSTM神经网络模型 3 预测效果3.1 Logistic回归模型3.2 SEITR模型3.3 LSTM神经网络模型 4 结论5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 …

智能优化算法应用:基于鱼鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于鱼鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于鱼鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.鱼鹰算法4.实验参数设定5.算法结果6.参考文献7.MA…

6、IDEA集成GitHub/码云

这里写目录标题 1、设置GitHub账号2、分享工程到GitHub3、Push推送本地库到远程库4、Pull拉取远程库到本地库5、Clone克隆远程库到本地6、码云简介 1、设置GitHub账号 可以采用两种登录方式&#xff1a;账户密码登入、口令登入。 2、分享工程到GitHub 先在GitHub中创建一个远…

【Hive_05】企业调优1(资源配置、explain、join优化)

1、 计算资源配置1.1 Yarn资源配置1.2 MapReduce资源配置 2、 Explain查看执行计划&#xff08;重点&#xff09;2.1 Explain执行计划概述2.2 基本语法2.3 案例实操 3、分组聚合优化3.1 优化说明&#xff08;1&#xff09;map-side 聚合相关的参数 3.2 优化案例 4、join优化4.1…

ARCGIS PRO SDK GeometryEngine处理独立几何图形的函数

1、面积类&#xff1a;pol为Polygon 1).Area&#xff1a;获取几何图形的面积。这是使用二维笛卡尔数学来计算面积的平面测量 double d GeometryEngine.Instance.Area(pol) 2).GeodesicArea:获取几何图形的椭球面积 …

highcharts的甘特图设置滚动时表头固定,让其他内容跟随滚动

效果图&#xff1a;最左侧的分类列是跟随甘特图滚动的&#xff0c;因为这一列如果需要自定义&#xff0c;比如表格的话可能会存在行合并的情况&#xff0c;这个时候甘特图是没有办法做的&#xff0c;然后甘特图的表头又需要做滚动时固定&#xff0c;所以设置了甘特图滚动时&…

Python测试框架pytest核心库pluggy详解

代码案例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 import pluggy # HookspecMarker 和 HookimplMarker 实质上是一个装饰器带参数的装饰器类&#xff0c;作用是给函数增加额外的…

【vue滚动条插件vuescroll】【vue自定义滚动条】

文章目录 前言一、使用步骤1.下载2.引入库三、在组件中如何使用&#xff1f;四、跳转到顶部的方法scrollTo() 五、效果总结 前言 由于浏览器自带的滚动条比较不符合设计图&#xff0c;所以在大部分项目中&#xff0c;我们都会自定义滚动条的样式&#xff0c;来还原设计图&…

策略模式(组件协作)

策略模式&#xff08;组件协作&#xff09; 链接&#xff1a;策略模式实例代码 注解 目的 正常情况下&#xff0c;一个类/对象中会包含其所有可能会使用的内外方法&#xff0c;但是一般情况下&#xff0c;这些常使用的类都是由不同的父类继承、组合得来的&#xff0c;来实现…