SrpingCloud网关路由、登录校验

SrpingCloud网关的作用

        我们知道前端发送请求到后端才能获取到数据再渲染到前端页面上去,但是微服务在不同的服务器端口上那么前端有没有一种简便的方法只用向后端的一个端口发送请求,就像springboot项目那样呢?有的,兄弟有的,这样的方法当然不止一种了。着重介绍一下SrpingCloud的网关。网关的一个很重要的作用就是对请求进行转发。

使用SrpingCloud网关进行请求路由

        首先网关也可以看做是一个微服务,这个微服务一个重要的作用就是就是将前端发送过来的请求转发到各个微服务中。

1、首先引入相关依赖

<!--网关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--nacos discovery-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--负载均衡-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
    </dependencies>

 2、编写启动类

ackage com.hmall.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

3、编写配置文件

server:
  port: 8080
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: 192.168.150.129:8848
    gateway:
      routes:
        - id: item-service # 路由规则id,自定义,唯一
          uri: lb://item-service # 路由的目标服务,lb代表负载均衡,会从注册中心拉取服务列表
          predicates: # 路由断言,判断当前请求是否符合当前规则,符合则路由到目标服务
            - Path=/items/**,/search/**
        - id: cart-service
          uri: lb://cart-service
          predicates:
            - Path=/carts/**
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/users/**,Path=/addresses/**
        - id: trade-service
          uri: lb://trade-service
          predicates:
            - Path=/trade/**
        - id: pay-service
          uri: lb://pay-service
          predicates:
            - Path=/pay/**


#注:    - Path=/items/**
        - Path=/items/**,/search/**
这样编写配置文件是错误的,这样默认要求两个都要满足,但是不可能同时满足这两种路由断言

这样就可以实现前端向后端8080端口发送请求,然后再又网关对请求进行转发

SrpingCloud网关的其他属性

        filters是对请求进行过滤的属性,也是比较常用的属性,这里列举一些常用的过滤器

 

网关实现登录校验

        要做登录校验我们需要拦截所有的请求来校验用户是否已经登录,你们上面的路由过滤器就不太够用了,我们需要使用全局过滤器来实现对所有路由进行过滤。

        GlobalFilter:全局过滤器,作用范围是所有路由;声明后自动生效。

 exchange对象就有我们所需要的用于做登录校验的数据,这里先模拟登录校验的逻辑,待会会将逻辑进行补全

public class MyGlobalFilter implements GlobalFilter , Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //TODO 模拟登录校验
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();
        System.out.println(headers);
        //将数据传递给下一个过滤器
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

看完这个示例我们就可以写一个登录校验的拦截器了


@Component
@RequiredArgsConstructor
public class AuthGlobalFilter implements GlobalFilter , Ordered {
    //解析jwt的类
    private final JwtTool  jwtTool;
    //存放需要拦截路径和不需要拦截路径的配置类
    private final AuthProperties  authProperties;
    //springcloud自带的路径匹配类
    private final AntPathMatcher  antPathMatcher = new AntPathMatcher();



    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取到请求体
        ServerHttpRequest request = exchange.getRequest();
        //判断是否放行
        if(isExclude(request.getPath().toString()))
        {
            //放行
            return chain.filter(exchange);
        }
        //获取token
        HttpHeaders headers = request.getHeaders();
        List<String> list = headers.get("authorization");
        String token = "";
        if(list != null && !list.isEmpty())
        {
            token = list.get(0);
        }
        //做登录校验
        Long userId = null;
        try{
            userId = jwtTool.parseToken(token);
        } catch (Exception e)
        {
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            response.setComplete();
        }
        //将数据传递给下一个微服务
        System.out.println(userId);
        //放行
        return chain.filter(exchange);
    }

    private boolean isExclude(String path) {
        List<String> excludePaths = authProperties.getExcludePaths();
        for (String excludePath : excludePaths) {
            if(antPathMatcher.match(excludePath, path))
            {
                return true;
            }
        }
        return false;
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

然后我们补全一下网关传递给其他微服务的逻辑:我们可以将用户的信息放在请求头中,再由网关发送请求到各个微服务,微服务之间可以使用@ReuqstHeader的注解获取请求头,但是这样获取方式比较繁琐,我们可以定义一个MVC拦截器来处理请求但是不做拦截,只获取请求并且存到当前线程当中,这样后端微服务就可以获取到前端穿过来的用户信息

1、将请求存到请求头

//将数据传递给下一个微服务
        String userinfo = userId.toString();
        exchange.mutate()
                .request(builder -> builder.header("userId", userinfo))
                .build();

2、编写MVC拦截器

public class UserInfoInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1.获取请求头中的用户信息
        String userInfo = request.getHeader("user-info");
        // 2.判断是否为空
        if (StrUtil.isNotBlank(userInfo)) {
            // 不为空,保存到ThreadLocal
                UserContext.setUser(Long.valueOf(userInfo));
        }
        // 3.放行
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 移除用户
        UserContext.removeUser();
    }
}

3、编写拦截器配置类

@Configuration
@ConditionalOnClass(DispatcherServlet.class)//网关也引用了common模块,网关不是基于SpringMVC,底层采用非阻塞式响应式编程是基于webflux,所以会有冲突,DispatcherServlet是SpringMVC的核心类所有用这个进行筛选
public class MvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new UserInfoInterceptor());
    }
}

4、配置META-INF/spring.factories

不过,需要注意的是,这个配置类默认是不会生效的,因为它所在的包是com.hmall.common.config,与其它微服务的扫描包不一致,无法被扫描到,因此无法生效。

基于SpringBoot的自动装配原理,我们要将其添加到resources目录下的META-INF/spring.factories文件中:

com.hmall.common.config.MvcConfig

这样就可以实现网关传递用户信息给其他微服务

是一个专门为提取和查看《大话西游》游戏素材而设计的软件集合。在这个工具集中,包含了多个不同的程序,每个程序都针对特定的文件类型和资源类型进行设计,以实现对游戏内各种资源的提取和查看。首先,WDF解压工具WdfRes_V1[1].1.24.exe是一个专门用来查看和解析WDF格式文件的工具。当使用这个工具查看软件后,它会在wdf文件的目录下自动生成一个名为.ResFiles的文件夹。在这个文件夹中,会包含各种资源文件,包括was资源或者音乐资源。这些资源文件对于游戏开发人员和爱好者来说是非常宝贵的,因为它们包含了游戏中各种图形和声音元素,可以用于游戏开发、素材研究或者个人兴趣。接着,waskey.exe是一个用来查看was格式动画的工具。was格式是《大话西游》中用于存储动画数据的一种格式。通过这个工具,用户能够查看游戏中角色的各种动画,如行走、跑动、攻击等动作的动画资源。wascompress.exe是一个工具,它能够将was格式的动画导出成tga格式的图片。TGA格式是一种图像文件格式,它广泛支持于不同的图形处理软件和游戏引擎中。通过将动画导出为TGA格式,可以直接进行打包,或者在Cocos等游戏开发框架中直接使用,这对于游戏开发人员来说是非常方便的。除了上述工具外,还有多个.wdf后缀的文件,它们分别对应《大话西游》游戏内的不同素材类型,包括:- misc.wdf:包含了游戏中的等待标志和时间等资源。- photo.wdf:包含了游戏内人物和NPC头像、以及对话时人物图像资源。- smap.wdf:包含了游戏的小地图资源。- shape.wdf:包含了人物、NPC和怪物的各个方向动作的资源。- shape.wd1:包含了转生人的各个方向动作资源,以及其他一些资源。- shape.wd2:包含了宝宝和转生宠物以及宠物法术的资源。- shape.wd3:包含了坐骑的各个方向动作资源。- addon.wdf:包含了游戏中各种小标志以及法术使用后的效果等资源。- card.wdf:包含了游戏卡牌的全部图片资源。- chat.wdf:包含了NPC的聊天文字资源。- magic.wdf:包含了游戏中各种法术的使用效果资源。- info.wdf:目前标记为"空",可能是一个待用的资源文件,或者是尚未使用的资源集。最后,sound.wdf和music.wdf包含了游戏中的音乐资源。其中,sound.wdf中的音乐资源可以通过修改文件后缀为mid格式来播放,而music.wdf中的音乐资源则可以通过修改文件后缀为mp3格式来播放。这个工具集合还包含了一个标签"大话 梦幻 素材 提取",这表明它主要应用于提取《大话西游》和《梦幻西游》这两款游戏中素材。"Glowtools"则可能是软件集合中的一个部分或者版本信息。综上所述,"大话西游素材提取工具(多个软件)"集合了一系列专业工具,旨在帮助用户提取、查看和使用《大话西游》游戏内的各种资源。这对于游戏开发人员、研究者以及对游戏素材感兴趣的用户都具有很大的价值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值