微服务---gateway网关

目录

gateway作用

gateway使用

添加依赖

配置yml文件

自定义过滤器

nacos上的gateway的配置文件


我们现在知道了通过nacos注册服务,通过feign实现服务间接口的调用,那对于不同权限的用户访问同一个接口,我们怎么知道他是否具有访问的权限呢?或者我们怎么判断是否用户已经登录了呢?这些都可以通过gateway进行实现~

gateway作用

        Spring Cloud Gateway是Spring Cloud生态系统中的一员,它被设计用于处理所有微服务的入口流量。作为一个反向代理,它不仅提供了负载均衡和路由功能,还支持灵活的过滤器机制,过滤器可以在请求进入网关和离开网关时执行,用于处理各种逻辑,如身份验证、日志记录和性能监测,使得开发者能够定制和扩展其功能。

下图提供了一个关于 Spring Cloud Gateway 如何工作的高层次概述。

        客户端向 Spring Cloud Gateway 发出请求。如果Gateway处理程序映射确定一个请求与路由相匹配,它将被发送到Gateway Web处理程序。这个处理程序通过一个特定于该请求的过滤器链来运行该请求。过滤器被虚线分割的原因是,过滤器可以在代理请求发送之前和之后运行逻辑。所有的 "pre" (前)过滤器逻辑都被执行。然后发出代理请求。在代理请求发出后,"post" (后)过滤器逻辑被运行。 

gateway使用

添加依赖

 <!--nacos服务注册发现依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--网关gateway依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!--开启Spring Cloud 应用程序启动时加载bootstrap配置文件--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId><version>3.1.4</version></dependency>

配置yml文件

gateway的配置文件其实就是将所有接口配置到web服务中,然后通过具体的过滤原则来访问每个接口

    其中- Authoriza=false表示是否需要通过token验证,这个为我们自定义的一个过滤原则名称的前缀,- StripPrefix=1为在发送请求时是否需要去掉第一层路径,比如/api/user/**如果StripPrefix=1表示api需要去掉,实际访问的是/user/**接口。

自定义过滤器

 AuthorizaGatewayFilterFactory使我们自定义的一个过滤器,gateway的自定义过滤器名字是有一定要求的,即 “你想取的过滤器名字前缀+GatewayFilterFactory”,这里以我的为例,然后把前缀作为刚刚配置文件的配置进行配置

然后我们实现这个自定义的过滤器

package com.yinan.authorize;import com.alibaba.fastjson.JSONArray;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.HttpHeaders;
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 java.util.Arrays;
import java.util.List;@Component
@Slf4j
@Data
@ConfigurationProperties(prefix ="exclude")
public class AuthorizaGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthorizaGatewayFilterFactory.Config> {/*** 需要放行的授权接口(nacos中的配置文件)*/private String[] path;@Autowiredprivate RedisTemplate<String, String> redisTemplate;/*** 授权token*/private static final String AUTHORIZE_TOKEN = "Authorization";/****/private static final String AUTHORIZE_IP = "x-access-ip";/*** 用来标记是否需要授权校验*/private static final String AUTHORIZE_RESOURCE = "x-access-resource";public AuthorizaGatewayFilterFactory() {super(Config.class);log.info("Loaded GatewayFilterFactory [Authorize]");}@Overridepublic List<String> shortcutFieldOrder() {return Arrays.asList("enabled");}@Overridepublic GatewayFilter apply(Config config) {log.info("你已经进入gateway的过滤器中了----------");return (exchange, chain) -> {if (!config.enabled) {return chain.filter(exchange);}ServerHttpRequest request = exchange.getRequest();ServerHttpResponse response = exchange.getResponse();HttpHeaders headers = request.getHeaders();ServerWebExchange build = null;//            从header中获取token信息String token = headers.getFirst(AUTHORIZE_TOKEN);//            获取用户IPString ip = headers.getFirst(AUTHORIZE_IP);log.info("当前访问url: " + request.getURI());if (token == null) {response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}log.info("请求的token为:" + token);log.info("请求的ip为:"+ ip);if (!"".equals(token)) {try {ValueOperations<String, String> value = redisTemplate.opsForValue();String userid = value.get(ip + "_user_" + "_userid_" + token);System.out.println("userid:"+ userid);String username = value.get(ip + "_user_" + "_username_" + token);String auth=value.get(ip+"_token_"+userid);if(auth==null){response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}
//            设置请求头ServerHttpRequest host = exchange.getRequest().mutate().headers(httpHeaders -> {httpHeaders.add("USER-ID", userid);httpHeaders.add("USER-NAME", username);}).build();build = exchange.mutate().request(host).build();
//            判断是否需要接口授权校验if (StringUtils.isNotBlank(headers.getFirst(AUTHORIZE_RESOURCE))) {Boolean authority = getAuthority(request.getURI().toString(), userid);if (authority) {response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}}
//            黑名单校验
//                    if (checkBlackList(ip, username)) {
//                        response.setStatusCode(HttpStatus.FORBIDDEN);
//                        return response.setComplete();
//                    }} catch (Exception e) {e.printStackTrace();
//                    token无效log.error("出现异常【{}】", e.getMessage());//设置状态码response.setStatusCode(HttpStatus.UNAUTHORIZED);return response.setComplete();}}
//认证通过,将用户ID进行传递到下游服务器return chain.filter(build);};}/*** 校验黑名单* @param ip* @param username* @return*/
//    private boolean checkBlackList(String ip, String username) {
//
//    }/***  获取用户权限(接口权限校验)* @param url* @param userid* @return*/private Boolean getAuthority(String url, String userid) {//放行接口不需要做授权校验,直接放行for (String path:path) {if(url.indexOf(path)!=-1){return false;}}//获取用户权限String resource=redisTemplate.opsForValue().get("userPermission:"+userid);List<String> list= JSONArray.parseArray(resource,String.class);for (String res:list) {if(url.indexOf(res)!=-1){return false;}}return true;}@Data@AllArgsConstructor@NoArgsConstructorpublic static class Config {/*** 控制是否开启认证*/private boolean enabled;}}

如果你看了我之前讲的nacos配置的内容,那你应该就能理解以下截图中的意思,没有了解过nacos的话建议先去看看以下文章:微服务----nacos配置及简单使用

nacos上的gateway的配置文件

management:# 端点检查(健康检查)endpoints:web:exposure:include: "*"
spring:profiles:active: devcloud:nacos:discovery:server-addr: 127.0.0.1:8848gateway:# 处理跨域globalcors:corsConfigurations:'[/**]':allowedHeaders: "*"allowedOrigins: "*"allowedMethods: "*"discovery:locator:# false为服务器名不自动匹配,true则相反enabled: false# 服务名以小写进行匹配lowerCaseServiceId: trueroutes:# web服务- id: service-1uri: lb://data-serverpredicates:- Path=/scriptsContent/**filters:#开启token验证- Authoriza=true- StripPrefix=0- id: service-2uri: lb://user-servicepredicates:- Path=/api/user/**filters:- Authoriza=false- StripPrefix=0#需要放行的授权接口
exclude:path:- /system/dictionary/by- /system/resource/by- /system/role/by- /system/api/user/by- /system/black/by- /oss- /web/article/by- /web/code/bypattern:dateformat: yyyy/MM/dd hh:mm:ss

以上就是我的具体的过滤器实现逻辑,但是需要根据你实际的项目代码逻辑对这个过滤器进行修改 。

        实现后,当前端调用你的接口时,会经过gateway网关中的过滤器看看你是否有这个权限进行访问,或者是否需需要经过登录后才能访问,如果以上都没问题,就会放行到下游过滤器继续进行检查,如果都没有问题最后就会调用到你的接口~

        以上几篇博文我们大致讲了一下微服务的搭建和使用,本人也是最近刚学会微服务,对于简单的微服务搭建你可以根据我的这几篇博文进行学习,如果版本这些没什么问题是肯定能实现的,至于这些技术较深的理解和学习如果你有兴趣可以继续进行专研学习,我们共同进步~

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

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

相关文章

python:画折线图

import pandas as pd import matplotlib.pyplot as plt from matplotlib.font_manager import FontProperties# 设置新宋体字体的路径 font_path D:/reportlab/simsun/simsun.ttf# 加载新宋体字体 prop FontProperties(fnamefont_path)""" # 读取 xlsx 文件 d…

leetcode每日一题第七十二天

class Solution { public:TreeNode* searchBST(TreeNode* root, int val) {if(!root) return root;if(root->val val) return root;else if(root->val > val) return searchBST(root->left,val);else return searchBST(root->right,val);} };

了解tensorflow.js

1、浏览器中进行机器学习的优势 浏览器中进行机器学习&#xff0c;相对比与服务器端来讲&#xff0c;将拥有以下四大优势&#xff1a; 不需要安装软件或驱动&#xff08;打开浏览器即可使用&#xff09;&#xff1b;可以通过浏览器进行更加方便的人机交互&#xff1b;可以通过…

5.06号模拟前端面试8问

5.06号模拟前端面试8问 1.promise如何实现then处理 在JavaScript中&#xff0c;Promise 是一个代表异步操作最终完成或失败的对象。它有三种状态&#xff1a;pending&#xff08;等待&#xff09;&#xff0c;fulfilled&#xff08;完成&#xff09;&#xff0c;rejected&…

【Git】Git学习-15:分支简介和基本操作

学习视频链接&#xff1a;【GeekHour】一小时Git教程_哔哩哔哩_bilibili​编辑https://www.bilibili.com/video/BV1HM411377j/?vd_source95dda35ac10d1ae6785cc7006f365780https://www.bilibili.com/video/BV1HM411377j/?vd_source95dda35ac10d1ae6785cc7006f365780 git bran…

Superset二次开发之XAxis 功能优化

背景&#xff1a; 以柱状图&#xff08;来自Echarts 插件&#xff09;为例&#xff0c;如果X轴data数据过长&#xff0c;影响图表体验&#xff0c;为此需要省略部分内容 superset-frontend\plugins\plugin-chart-echarts\src\Timeseries\transformProps.ts import {getBaselin…

【C++】string类的使用②(容量接口Capacity || 元素获取Element access)

&#x1f525;个人主页&#xff1a; Forcible Bug Maker &#x1f525;专栏&#xff1a; STL || C 目录 前言&#x1f525;容量接口&#xff08;Capacity&#xff09;size和lengthcapacitymax_sizereserveresizeclearemptyshrink_to_fit &#x1f525;元素获取&#xff08;Ele…

【华为】IPSec VPN手动配置

【华为】IPSec VPN手动配置 拓扑配置ISP - 2AR1NAT - Easy IPIPSec VPN AR3NATIPsec VPN PC检验 配置文档AR1AR2 拓扑 配置 配置步骤 1、配置IP地址&#xff0c;ISP 路由器用 Lo0 模拟互联网 2、漳州和福州两个出口路由器配置默认路由指向ISP路由器 3、进行 IPsec VPN配置&…

Web 安全基础理论

Web 安全基础理论 培训、环境、资料、考证 公众号&#xff1a;Geek极安云科 网络安全群&#xff1a;624032112 网络系统管理群&#xff1a;223627079 网络建设与运维群&#xff1a;870959784 移动应用开发群&#xff1a;548238632 短视频制作群&#xff1a; 744125867极安云…

nginx代理原理(端口复用)探究

前言&#xff1a;对于一些常用的插件&#xff0c;我们应该学会如何使用。同时&#xff0c;其实现原理也要进行深究&#xff0c;可以为其他的项目开发做借鉴。 探究方案&#xff1a; 一、发布两个不同的服务&#xff0c;这两个服务的端口不致 二、配置nginx&#xff0c;让这两…

2024年美国市场亚太游戏品牌数字广告洞察报告

来源&#xff1a;Sensor Tower 美国是全球最大的游戏市场之一&#xff0c;也是亚太游戏品牌出海的重要市场。2023年Q2至2024年Q1&#xff0c;美国市​场广告投放额排名前10的亚太游戏品牌&#xff0c;合计支出 超过7.5亿美元&#xff0c;环比上涨23%。 排名第一的米哈游(miHoY…

免费思维13招之二:第三方思维

思维02:第三方思维 第三方思维又叫第三方资费思维。是一种可以使你的产品免费但是你却依然赚钱的思维。 大家还记得之前讲的“餐厅免费吃饭却年赚百万”的案例吗?这个案例运用了多种免费思维的子思维,其中也用到了第三方资费思维,怎么运用的呢?韩女士,与各行各业合作,…

【C语言】内存函数的概念,使用及模拟实现

Tiny Spark get dazzling some day. 目录 1. memcpy-- 函数原型-- 函数使用-- 函数的模拟实现 2.memmove-- 函数原型-- 函数使用-- 函数的模拟实现 3. memset-- 函数原型-- 函数使用-- 函数的模拟实现 4. memcmp-- 函数原型-- 函数使用-- 函数的模拟实现 1. memcpy 使用需包含…

BI赋能金融新质生产力,16家金融机构智能BI创新实践分享

2024年政府工作报告强调&#xff0c;要“大力发展科技金融、绿色金融、普惠金融、养老金融、数字金融”&#xff0c;同时“大力推进现代化产业体系建设&#xff0c;加快发展新质生产力”。对于金融行业而言&#xff0c;培育新质生产力是高质量发展的关键着力点。金融机构可以通…

【JavaWeb】Servlet+JSP+EL表达式+JSTL标签库+Filter过滤器+Listener监听器

需要提前准备了哪些技术&#xff0c;接下来的课才能听懂&#xff1f; JavaSE&#xff08;Java语言的标准版&#xff0c;Java提供的最基本的类库&#xff09; Java的开发环境搭建Java的基础语法Java的面向对象数组常用类异常集合多线程IO流反射机制注解Annotation… MySQL&…

FinalShell连接虚拟机Linux系统连接超时

报错信息 java.net.ConnectException: Connection timed out: connect 排除是网络问题后可以尝试一下这个方法。 解决方案: 打开虚拟机终端输入:ifconfig 会出现端口信息: 看ens33这里的端口是多少&#xff0c;改一下重新连接就ok。

保研面试408复习 4——操作系统、计网

文章目录 1、操作系统一、文件系统中文件是如何组织的&#xff1f;二、文件的整体概述三、UNIX外存空闲空间管理 2、计算机网络一、CSMA/CD 协议&#xff08;数据链路层协议&#xff09;二、以太网MAC帧MTU 标记文字记忆&#xff0c;加粗文字注意&#xff0c;普通文字理解。 1、…

系统运维(虚拟化)

1.VLAN VLAN&#xff08;Virtual Local Area Network&#xff09;即虚拟局域网&#xff0c;是将一个物理的LAN在逻辑上划分成多个广播域的通信技术。 每个VLAN是一个广播域&#xff0c;VLAN内的主机间可以直接通信&#xff0c;而VLAN间则不能直接互通。这样&#xff0c;广播报…

C++ | Leetcode C++题解之第61题旋转链表

题目&#xff1a; 题解&#xff1a; class Solution { public:ListNode* rotateRight(ListNode* head, int k) {if (k 0 || head nullptr || head->next nullptr) {return head;}int n 1;ListNode* iter head;while (iter->next ! nullptr) {iter iter->next;n…

Spring Boot 整合 socket 实现简单聊天

来看一下实现的界面效果 pom.xml的maven依赖 <!-- 引入 socket --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><!-- 引入 Fastjson &#x…