【SpringCloud】Gateway微服务网关(gateway快速⼊⻔ 断⾔⼯⼚ 过滤器⼯⼚ 浏览器同源策略)

news2024/11/27 14:48:33

Gateway微服务网关

  • Gateway服务网关
    • 什么是Gateway网关?
      • 为什么需要网关?
    • Gateway快速入门
      • 创建gateway服务,引入依赖
      • 编写配置文件yaml和路由规则
      • 重启测试
    • 断言工厂
    • 过滤器工厂
      • 路由过滤器的种类
      • 请求头过滤器
      • 默认过滤器
      • 全局过滤器【可写自定义逻辑】
      • 自定义全局过滤器【自定义Auth认证】
      • 过滤器执行顺序
          • 过滤器执⾏顺序
          • 测试优先级
    • 浏览器同源策略
    • 跨域问题解决方案
  • 前后端设计:
      • 单体架构
      • 微服务架构

Gateway服务网关

什么是Gateway网关?

Spring Cloud Gateway 是 Spring Cloud 的⼀个全新项⽬,该项⽬是基于 Spring 5.0,Spring Boot 2.0 和Project Reactor 等响应式编程和事件流技术开发的⽹关,它旨在为微服务架构提供 ⼀种简单有效的统⼀的 API 路由管理⽅式。

为什么需要网关?

Gateway⽹关是我们服务的守⻔神,所有微服务的统⼀⼊⼝。

⽹关的核⼼功能特性:

  • 请求路由
  • 权限控制
  • 限流

整体架构为:

**权限控制:**⽹关作为微服务⼊⼝,需要校验⽤户是否有请求资格,如果没有则进⾏拦截。

**路由和负载均衡:**⼀切请求都必须先经过gateway,但⽹关不处理业务,⽽是根据某种规则,把请求转发到某个微服务,这个过程叫做路由。当然路由的⽬标服务有多个时,还需要做负载均衡。

**限流:**当请求流量过⾼时,在⽹关中按照下流的微服务能够接受的速度来放⾏请求,避免服务压⼒过⼤。

在SpringCloud中网关的实现包括两种:

  • Gateway【基于Spring5中提供的 WebFlux,属于响应式编程的实现,具备更好的性能】
  • zuul【基于Servlet的实现,是属于阻塞式编程】

Gateway快速入门

基本步骤如下:

  1. 创建SpringBoot⼯程gateway,引⼊⽹关依赖
    2.编写基础配置和路由规则
  1. 启动⽹关服务进⾏测试

创建gateway服务,引入依赖

新增模块gateway

导入pom坐标

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>springcloud_alibaba</artifactId>
        <groupId>com.stringzhua</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>api-gateway</artifactId>

    <dependencies>
        <!--gateway网关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--nacos客户端-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>

</project>

编写配置文件yaml和路由规则

server:
  port: 7000
spring:
  application:
    name: api-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      discovery:
        locator:
          enabled: true # 让gateway可以发现nacos中的微服务
      routes: # 路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]
        - id: product_route # 当前路由的标识, 要求唯一
          uri: lb://service-product # 请求要转发到的地址
          order: 1 # 路由的优先级,数字越小级别越高
          predicates: # 断言(就是路由转发要满足的条件)
            - Path=/product-serv/** # 当请求路径满足Path指定的规则时,才进行路由转发
          filters: # 过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
            - StripPrefix=1 # 转发之前去掉1层路径
        - id: order_route # 当前路由的标识, 要求唯一
          uri: lb://service-order # 请求要转发到的地址
          order: 1 # 路由的优先级,数字越小级别越高
          predicates: # 断言(就是路由转发要满足的条件)
            - Path=/order-serv/** # 当请求路径满足Path指定的规则时,才进行路由转发
          filters: # 过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
            - StripPrefix=1 # 转发之前去掉1层路径

重启测试

这里我们使用了nacos的lb轮询策略,而不是把服务的端口号写死:

总结

网关搭建步骤:

  • 1.创建项目,引入nacos服务发现和gateway依赖
  • 2.配置application.yaml,包括服务基本信息、nacos地址、路由

路由配置包括:

  • 1.路由id:路由的唯一标识
  • 2.路由目标uri:路由的目标地址,http代表固定地址,lb代表根据服务名负载均衡
  • 3.路由断言predicates:判断路由的规则
  • 4.路由过滤器filters:对请求或响应做处理

断言工厂

我们在配置⽂件中写的断⾔规则只是字符串,这些字符串会被Predicate Factory读取并处理,转 变为路由判断的条件 例如Path=/user/**是按照路径匹配,这个规则是由org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类来处理 的,像这样的断⾔⼯⼚在SpringCloudGateway还有⼗⼏个:

例如:

After=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]

那么就会访问不到:

改为:

Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]

就可以访问到:

过滤器工厂

GatewayFilter是⽹关中提供的⼀种过滤器,可以对进⼊⽹关的请求和微服务返回的响应做处理:

路由过滤器的种类

Spring提供了31种不同的路由过滤器⼯⼚

请求头过滤器

下⾯我们以AddRequestHeader 为例来讲解。 限制请求的流量 只需要修改gateway服务的application.yml⽂件,添加路由过滤即可:

server:
  port: 7000
spring:
  application:
    name: api-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      discovery:
        locator:
          enabled: true # 让gateway可以发现nacos中的微服务
      routes:
        - id: product_route
          uri: lb://service-product # lb指的是从nacos中按照名称获取微服务,并遵循负载均 衡策略
          order: 1
          predicates:
            - Path=/product-serv/**
            - Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]
          filters:
            - StripPrefix=1
            - AddRequestHeader=msg,wake up! # 添加请求头

修改ProductController

//路由过滤器
    @RequestMapping("/productheader")
    public String productHeader(@RequestHeader(value = "msg",required = false)String msg){
        System.out.println("=====>头信息:"+msg);
        return "productHeader";
    }

访问会得到如下头信息:

默认过滤器

GatewayFilter是⽹关中提供的⼀种过滤器,可以对进⼊⽹关的请求和微服务返回的响应做处理:

如果要对所有的路由都⽣效,则可以将过滤器⼯⼚写到default下。格式如下:

server:
  port: 7000
spring:
  application:
    name: api-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      discovery:
        locator:
          enabled: true # 让gateway可以发现nacos中的微服务
      routes:
        - id: product_route
          uri: lb://service-product # lb指的是从nacos中按照名称获取微服务,并遵循负载均 衡策略
          order: 1
          predicates:
            - Path=/product-serv/**
            - Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]
          filters:
            - StripPrefix=1
            - AddRequestHeader=msg,wake up product_route! # 添加请求头
      default-filters: # 默认过滤器,会对所有的路由请求都⽣效
        - AddRequestHeader=msg,wake up default-filters! # 添加请求头

全局过滤器【可写自定义逻辑】

概念

**全局过滤器作用 **全局过滤器的作⽤也是处理⼀切进⼊⽹关的请求和微服务响应,与GatewayFilter的作⽤⼀样。

区别在于GatewayFilter通过配置定义,处理逻辑是固定的;

⽽GlobalFilter的逻辑需要⾃⼰写代码实现。 定义⽅式是实现GlobalFilter接⼝。

在filter中编写⾃定义逻辑,可以实现下列功能:

  • 登录状态判断
  • 权限校验
  • 请求限流等

自定义全局过滤器【自定义Auth认证】

需求:定义全局过滤器,拦截请求,判断请求的参数是否满⾜下⾯条件:

  • 参数中是否有authorization
  • authorization参数值是否为admin

如果同时满⾜则放⾏,否则拦截

实现:在gateway中定义⼀个过滤器:

首先在gateway中定义一个过滤规则:

package com.stringzhua.shop_gateway.filters;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @Author Stringzhua
 * @Date 2024/10/8 15:58
 * description:
 */
@Order(-1)//设置优先级
@Component
public class AuthorizeFilter implements GlobalFilter {
    //Mono<Void> 无状态的返回值,不会立即执行
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        System.out.println("自定义全局过滤器~");
//        return chain.filter(exchange);

        //1.获取请求参数
        String auth = exchange.getRequest().getHeaders().get("authorization").get(0);

        //2.校验
        if ("admin".equals(auth)) {
            //放行
            return chain.filter(exchange);
        }
        //3.拦截
        //3.1禁止访问
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        //3.2结束处理,返回数据
        return exchange.getResponse().setComplete();
    }
}

重启gateway项目,然后发送请求测试http://localhost:7000/product-serv/product/6?authorization=admin或者postman 测试

这里使用postman测试在Postman中访问:http://localhost:7000/product-serv/product/select/11

过滤器执行顺序

过滤器执⾏顺序

请求进⼊⽹关会碰到三类过滤器:当前路由的过滤器、DefaultFilter、GlobalFilter 请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到⼀个过滤器链(集合) 中,排序后依次执⾏每个过滤器

排序规则是什么?

  • 每⼀个过滤器都必须指定⼀个int类型的order值,order值越⼩,优先级越⾼,执⾏顺序越靠前。
  • GlobalFilter通过实现Ordered接⼝,或者添加@Order注解来指定order值,由我们⾃⼰指定
  • 路由过滤器和defaultFilter的order由Spring指定,默认是按照声明顺序从1递增。
  • 当过滤器的order值⼀样时,会按照 defaultFilter > 路由过滤器 >GlobalFilter的顺序执⾏。
测试优先级
package com.stringzhua.shop_gateway.filters;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @Author Stringzhua
 * @Date 2024/10/8 15:58
 * description:
 */
@Order(-1)//设置优先级
@Component
public class AuthorizeFilter implements GlobalFilter {
    //Mono<Void> 无状态的返回值,不会立即执行
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("自定义全局过滤器~");
        return chain.filter(exchange);
    }
}

优先级为:默认过滤器,路由过滤器,全局过滤器【自定义】

浏览器同源策略

1995年,同源政策由 Netscape 公司引⼊浏览器。⽬前,所有浏览器都实⾏这个政策。

最初,它的含义是指,A⽹⻚设置的 Cookie,B⽹⻚不能打开,除⾮这两个⽹⻚"同源"。所谓"同源"指的 是"三个相同"。

  • 协议相同
  • 域名相同
  • 端⼝相同

举例: http://www.example.com/dir/page.html⽹址

  • 协议是http://
  • 域名是www.example.com
  • 端⼝是80(默认端⼝可以省略)

它的同源情况如下

  • http://www.example.com/dir2/other.html:同源
  • http://example.com/dir/other.html:不同源(域名不同)
  • http://v2.www.example.com/dir/other.html:不同源(域名不同)
  • http://www.example.com:81/dir/other.html:不同源(端⼝不同)

同源⽬的

同源政策的⽬的,是为了保证⽤户信息的安全,防⽌恶意的⽹站窃取数据。

设想这样⼀种情况:A⽹站是⼀家银⾏,⽤户登录以后,⼜去浏览其他⽹站。如果其他⽹站可以读取A⽹ 站的 Cookie,会发⽣什么?

很显然,如果 Cookie 包含隐私(⽐如存款总额),这些信息就会泄漏。更可怕的是,Cookie 往往⽤来保存⽤户的登录状态,如果⽤户没有退出登录,其他⽹站就可以冒充⽤户,为所欲为。因为浏览器同时还规定,提交表单不受同源政策的限制。

由此可⻅,"同源政策"是必需的,否则 Cookie 可以共享,互联⽹就毫⽆安全可⾔了。

跨域问题解决方案

跨域:域名不⼀致就是跨域,主要包括:

  • 域名不同: www.taobao.com 和 www.taobao.org 和 www.jd.com 和 miaosha.jd.com
  • 域名相同,端⼝不同:localhost:8080和localhost8081

跨域问题:浏览器禁⽌请求的发起者与服务端发⽣跨域ajax请求,请求被浏览器拦截的问题

**CORS **

CORS是跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是W3C标准,是跨源AJAX请求 的根本解决⽅法。相⽐JSONP只能发GET请求,CORS允许任何类型的请求。

在gateway服务的application.yml⽂件中,添加下⾯的配置:

spring:
  cloud:
    gateway:
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
        corsConfigurations:
          '[/**]':
            allowedOrigins: # 允许哪些⽹站的跨域请求
              - "http://localhost:8090"
            allowedMethods: #允许的跨域ajax的请求⽅式              
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" #允许在请求中携带的头信息            
            allowCredentials: true #是否允许携带cookie
            maxAge: 360000 #这次跨域检测的有效期

前后端设计:

单体架构

有状态的认证:

首先前端接收用户输入的账号和密码,通过表单的形式提交到后台,后台查询数据库是否存在该用户对象,将用户对象信息保存至session再返回给前端一个登录成功状态。

当下次登录时,检查session会话中是否有该对象,如果有就登录成功,没有则需要重定向到登录界面。

无状态的认证:【主流】

首先前端接收用户输入的账号和密码,通过前端提交到后台,后台查询到数据库中是否存在该用户对象,将该用户的对象信息转换为token串,再和登录成功信息一起返回给前端。

当下次登录时,后端检查前端发送的请求头中是否携带有效token,如果有则登录成功,没有则跳转到登录界面重新登录。

微服务架构

有状态的认证:【不推荐】

无状态的认证:【借助网关实现,推荐】

无状态Token方案是一种基于Token的认证方式,用户登录成功后,服务器会返回一个Token给客户端,客户端每次请求都需要携带这个Token。 服务器通过验证Token的有效性来判断用户的身份和权限。 由于Token是无状态的,即不包含用户的状态信息,因此服务器不需要保存Token的状态,也不需要跨域共享Session。

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

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

相关文章

IT监控(基础篇):好的it监控系统具备什么特点?

好的IT监控系统&#xff0c;应该是什么样的呢&#xff1f; 在当今数字化时代&#xff0c;IT系统已成为企业运营的命脉。因此&#xff0c;一个高效、可靠的IT监控平台对于确保业务连续性和提高运维效率至关重要。那么&#xff0c;一个好的IT监控平台究竟应该具备哪些特点呢&…

Adobe Acrobat DC 打印PDF文件,没有打印出注释的解决方法

adobe acrobat在打印的时候&#xff0c;打印不出来注释内容&#xff08;之前一直可以&#xff0c;突然就不行&#xff09;&#xff0c;升级版本、嵌入字体等等都试过&#xff0c;也在Google找了半天和问了GPT也么找着办法。 无奈之下&#xff0c;自己通过印前检查&#xff0c;…

ARL 灯塔 | CentOS7 — ARL 灯塔搭建流程(Docker)

关注这个工具的其它相关内容&#xff1a;自动化信息收集工具 —— ARL 灯塔使用手册 - CSDN 博客 灯塔&#xff0c;全称&#xff1a;ARL 资产侦察灯塔系统&#xff0c;有着域名资产发现和整理、IP/IP 段资产整理、端口扫描和服务识别、WEB 站点指纹识别、资产分组管理和搜索等等…

Elasticsearch是做什么的?

初识elasticsearch 官方网站&#xff1a;Elasticsearch&#xff1a;官方分布式搜索和分析引擎 | Elastic Elasticsearch是做什么的&#xff1f; Elasticsearch 是一个分布式搜索和分析引擎&#xff0c;专门用于处理大规模数据的实时搜索、分析和存储。它基于 Apache Lucene …

Spring MVC 原理与源码

Spring MVC 整体代码量有 5w 行&#xff0c;通过本专栏&#xff0c;可以快速的研读核心部分的代码&#xff0c;节省你的时间。 DispatcherServlet 的流程处理如下图&#xff1a; 但是随着前后端分离&#xff0c;后端大多提供 Restful API &#xff0c;里面的 ViewResolver 和 …

监控易监测对象及指标之:Kafka中间件JMX监控指标解读

监控易作为一款功能强大的监控软件&#xff0c;旨在为企业提供全方位的IT系统监控服务。其中&#xff0c;针对Kafka中间件的JMX监控是监控易的重要功能之一。本文将详细解读监控易中Kafka的JMX监控指标&#xff0c;帮助企业更好地理解并运用这些数据进行系统性能调优和故障排查…

onlyoffice docker启用jwt并生成jwt

一、说明 本文是docker教程&#xff0c;linux/win的安装版本也类似&#xff0c;只需要修改配置文件中的secrt就可以了【Configuring JWT for ONLYOFFICE Docs - ONLYOFFICE】 二、正文开始 docker启动时候如果不想使用jwt&#xff0c;加上参数-e JWT_ENABLEDfalse就可以了&…

软件I2C的代码

I2C的函数 GPIO的配置——scl和sda都配置为开漏输出 void MyI2C_Init(void) {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);GPIO_InitTypeDef GPIO_InitStruture;GPIO_InitStruture.GPIO_Mode GPIO_Mode_Out_OD;GPIO_InitStruture.GPIO_PinGPIO_Pin_10 | GPIO_Pin_…

Maven 项目管理工具

目录 Maven简介 Maven快速上手 Maven详细介绍 Maven工作机制 Maven安装及配置 使用IDEA创建Maven Web工程 Maven简介 Maven是 Apache 开源组织奉献的一个开源项目&#xff0c;可以翻译为“专家”或“内行”。 Maven 的本质是一个项目管理工具&#xff0c;将项目开发和管…

Ansible自动化工具

一、Ansible概述 1.1 什么是Ansible Ansible 是一个开源的自动化工具&#xff0c;用于配置管理、应用程序部署和任务自动化。它让你可以通过编写简单的 YAML 文件&#xff08;剧本&#xff0c;Playbooks&#xff09;&#xff0c;轻松管理和配置多个服务器。Ansible 的特点是无…

爬虫逆向-js进阶(续写,搭建网站)

1.搭建简单网站1 from flask import Flask,render_template import requests import json app Flask(name)# **location**的温度是**temp**度&#xff0c;天气状况&#xff1a;**desc**app.route(/) # 绑定处理函数 def index_url():location 101010100data get_weather(lo…

Rust语言编程环境的安装

简介 Rust是一门系统编程语言,专注于安全,尤其是并发安全,支持函数式和命令式以及泛型等编程范式的多范式语言。 Rust语言的特点 系统级编程:Rust语言非常适合进行底层系统级编程,如操作系统、网络协议栈、设备驱动程序等。 内存安全:Rust使用所有权(ownership)系统来…

Scrapy | 爬取笑话网来认识继承自Spider的crawlspider爬虫类

crawlspider 1. 创建crawlspider爬虫2. 实战-爬取笑话网笑话 本篇内容旨在拓展视野和知识&#xff0c;了解crawlspider的使用即可&#xff0c;主要熟悉掌握spider类的使用 CrawlSpider 提供了一种更高级的方法来定义爬取规则&#xff0c;而无需编写大量的重复代码。它基于规则…

【功能安全】汽车功能安全个人认证证书

目录 1、证书 2、课程信息 &#x1f4d6; 推荐阅读 1、证书 汽车功能安全工程师去拿类似莱茵、SGS、南德颁发的证书&#xff0c;如下&#xff1a; 2、课程信息 一般上什么课程了&#xff0c;课程信息大概如下&#xff1a; 汽车功能安全工程师认证课 &#xff08;3天&#…

【Linux】进程的挂起状态

挂起状态的前提条件 当 内存资源严重不足 时&#xff0c;操作系统会考虑将部分进程换出到磁盘上的交换空间&#xff08;swap 分区&#xff09;。这通常发生在以下几种情况下&#xff1a; 内存不足&#xff1a; 当物理内存接近耗尽时&#xff0c;操作系统会选择将一部分暂时不需…

查缺补漏----数据结构树高总结

① 对于平衡二叉树而言&#xff0c;树高的规律&#xff1a; 高度为h的平衡二叉树的含有的最少结点数&#xff08;所有非叶节点的平衡因子均为1&#xff09;&#xff1a; n01&#xff0c;n11&#xff0c;n22 含有的最多结点数&#xff1a; (高度为h的满二叉树含有的结点数) ②…

监控内容、监控指标、监控工具大科普

在现代信息技术领域&#xff0c;监控技术扮演着至关重要的角色。它帮助我们实时了解系统、网络、应用以及环境的状态&#xff0c;确保它们的安全、稳定和高效运行。以下是对监控内容、监控指标和监控工具的详细科普。 一、监控内容 监控内容是指监控系统所关注和记录的具体信…

C++面向对象编程学习

C面向对象编程学习 前言一、C面向对象编程二、知识点学习1. 定义一个类1.1 使用struct定义1.2 使用class定义1.3 struct和class的区别 2. 类的定义方式2.1 单文件定义&#xff08;Inline Definition&#xff09;2.2 分离定义&#xff08;Separate Definition&#xff09;2.3 头…

一文2500字从0到1实现压测自动化!

大家好&#xff0c;我是小码哥&#xff0c;最近工作有点忙&#xff0c;一直在实现压测自动化的功能&#xff0c;今天来分享一下实现思路 我所在的业务线现在项目比较少了&#xff0c;所以最近一个月我都没有做业务测试&#xff0c;需求开发完后RD直接走免测就上线&#xff0c;…

利用Spring Boot实现信息化教学平台

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理信息化在线教学平台的相关信息成为必然。开…