微服务---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.mzph.cn/pingmian/6891.shtml

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

相关文章

Verilog中求两个数的差值

根据输入信号a,b的大小关系&#xff0c;求解两个数的差值&#xff1a;输入信号a,b为8bit位宽的无符号数。如果a>b&#xff0c;则输出a-b&#xff0c;如果a≤b&#xff0c;则输出b-a。 接口信号图如下&#xff1a; 代码如下&#xff1a; &#xff08;CSDN代码块不支持Veril…

WPF之绑定属性值转换

1&#xff0c;使用Binding.Format属性简易设置绑定的属性数据显示格式。 <TextBox Grid.Row"2" Grid.Column"1"><TextBox.Text><Binding Path"UnitCost" StringFormat"{}{0:C3}" > …

加州大学欧文分校英语中级语法专项课程02:Adjectives and Adjective Clauses 学习笔记

Adjectives and Adjective Clauses course certificate 本文是 https://www.coursera.org/learn/adjective-clauses 这门课的学习笔记。 文章目录 Adjectives and Adjective ClausesWeek 01: Adjectives and Adjective PhrasesLearning Objectives Adjectives Introduction Le…

一个新细节,Go 1.17 将允许切片转换为数组指针!

在 Go 语言中&#xff0c;一个切片&#xff08;slice&#xff09;包含了对其支持数组的引用&#xff0c;无论这个数组是作为一个独立的变量存在于某个地方&#xff0c;还是仅仅是一个为支持分片而分配的匿名数组。 其切片基本结构都如下&#xff1a; // runtime/slice.go typ…

ChatGPT 4.0 直接用 !!!Code Copilot编程大模型、DALL-E AI绘图、绘制流程图、上传文件

嗨&#xff0c;你好呀&#xff0c;我是哪吒。 这一年最让人揪心的热点&#xff0c;就是各种层出不穷的AI技术。 原以为它只是短暂霸屏&#xff0c;但现实却赤裸裸展示了&#xff0c;什么叫AI抢走你的饭碗&#xff0c;连招呼都不打一声! 什么策划方案、公众号文案、营销卖点、…

学术咸鱼入门指南(1)

学术基础素养 一.巧用工具管理文献&#xff0c;形成自己的文献体系 养成习惯的第一步&#xff1a;文献命名 当你下载完一篇文献&#xff0c;应该做的第一步就是给文献重新命名。命名的逻辑可以随自己的喜好来&#xff0c;可以按照“发表年份作者文章标题”。 也可以使用文献…

利用策略模式+模板方法实现项目中运维功能

前段时间项目中有个需求&#xff1a;实现某业务的运维功能&#xff0c;主要是对10张数据库表的增删改查&#xff0c;没有复杂的业务逻辑&#xff0c;只是满足运维人员的基本需要&#xff0c;方便他们快速分析定位问题。这里简单记录分享下实现方案&#xff0c;仅供参考。 一、…

多模态路径:利用其他模态的无关数据改进变压器(CVPR 2024)

<Multimodal Pathway: Improve Transformers with Irrelevant Data from Other Modalities> 论文地址&#xff1a;https://arxiv.org/abs/2401.14405 项目网页&#xff1a;https://ailab-cvc.github.io/M2PT/ 开源代码&#xff1a;https://github.com/AILab-CVC/M2PT 讲…

vue快速入门(五十七) 作用域插槽

注释很详细&#xff0c;直接上代码 上一篇 新增内容 作用域插槽实现表格删除数据 源码 App.vue <template><div id"app"><!-- 向子组件传值 --><MyTable :tableData"tableData"><!-- 接收子组件的传值&#xff0c;默认是对象格…

Web3 ETF的基本概念

Web3 ETF&#xff08;Exchange-Traded Fund&#xff0c;交易所交易基金&#xff09;是一种投资工具&#xff0c;它允许投资者通过购买单一的基金份额来获得对多个与Web3技术相关的公司和资产的曝光。Web3技术通常指的是基于区块链构建的去中心化网络和应用&#xff0c;包括加密…

时间复杂度空间复杂度 力扣:转轮数组,消失的数字

1. 算法效率 如何衡量一个算法的好坏&#xff1f;一般是从时间和空间的维度来讨论复杂度&#xff0c;但是现在由于计算机行业发展迅速&#xff0c;所以现在并不怎么在乎空间复杂度了下面例子中&#xff0c;斐波那契看上去很简洁&#xff0c;但是复杂度未必如此 long long Fib…

【深度学习实战(31)】模型结构之CSPDarknet

文章目录 一、CSPDarknet整体结构二、CSPNet结构2.1 里面小残差结构Bottleneck2.2 外层大残差结构CSP 三、SPP结构四、CSPDarknet结构4.1 stem结构4.2 dark2,3,4结构&#xff0c;dark3为例&#xff1a;4.3 dark5结构4.4 CSPDarkNet整体结构 四、完整代码 一、CSPDarknet整体结构…

通过DataGrip将mysql表结构信息转存excel 复制select结果的insert插入语句

各位小伙伴们大家好&#xff0c;欢迎来到这个小扎扎的专栏 总结 | 提效 | 拓展&#xff0c;在这个系列专栏中记录了博主在学习期间总结的大块知识点&#xff0c;以及日常工作中遇到的各种技术点 ┗|&#xff40;O′|┛ &#x1f306; 内容速览 1 查询表结构信息&#xff0c;并…

[安洵杯 2019]JustBase(替换表)

题目&#xff1a; 我们看到题目是一些杂乱的字母和符号&#xff0c;但从题目和末尾的两个号&#xff0c;我们猜测是base64加密&#xff0c;但题目未出现1-9数字&#xff0c;而base64不包含!#$%等字符&#xff0c;所以我们考虑将字符!#$%按照键盘替换成数字1-9. 替换代码如下&a…

基于光伏电站真实数据集的深度学习预测模型(Python代码,深度学习五个模型)

效果视频链接&#xff1a;基于深度学习光伏预测系统&#xff08;五个模型&#xff09;_哔哩哔哩_bilibili 界面设计 注册界面 登录界面 主界面 展示界面 1.数据集来源 The SOLETE dataset 这里分别保存了不同间隔采样时间表格 1min是以1min 间隔采集的数据集 数据集截图&…

Java 中的 pyftpdlib 替代品

在 Java 中&#xff0c;有一些替代方案可以用来实现 FTP 服务器功能&#xff0c;类似于 Python 中的 pyftpdlib。目前我们常用的就是三种替换方案&#xff0c;这里需要根据自己的项目需求选择合适的方法。 1、问题背景 在 Java 环境下寻找一款与 pyftpdlib 类似的 FTP 服务器库…

企业开发基础--数据库

今天完成了数据库学习的全部内容&#xff0c;在事务&#xff0c;索引&#xff0c;范式中要有个人逻辑上的理解&#xff0c;也算是卡着点完成了大多数预期&#xff0c;还有一个Java游戏未完成&#xff0c;会后续补上。 之后的一周要完成34道数据库练习题以及JDBC&#xff0c;学…

ip地址快速切换软件是什么

ip地址快速切换软件是什么&#xff1f;随着互联网的发展&#xff0c;IP地址变得愈发关键。对于网络工作者、营销人员和游戏玩家&#xff0c;频繁更换IP地址成了日常工作需求。为满足这一需求&#xff0c;IP地址快速切换软件如虎观代理IP软件应运而生&#xff0c;它为用户提供了…

避雷!7.7分,新增1区TOP被标记On Hold,5本已被踢除!

本周投稿推荐 SSCI • 2/4区经管类&#xff0c;2.5-3.0&#xff08;录用率99%&#xff09; SCIE&#xff08;CCF推荐&#xff09; • 计算机类&#xff0c;2.0-3.0&#xff08;最快18天录用&#xff09; SCIE&#xff08;CCF-C类&#xff09; • IEEE旗下&#xff0c;1/2…

低代码技术的深度应用:物资管理的创新与效率提升

引言 在当今企业运营中&#xff0c;物资管理扮演着至关重要的角色。无论是制造业、零售业还是服务行业&#xff0c;有效的物资管理都是确保业务正常运转和持续发展的关键。然而&#xff0c;随着企业规模的扩大和业务的复杂化&#xff0c;物资管理也变得越来越复杂。企业需要管…