网关中配置过滤器

本文介绍了如何在Spring Cloud Gateway中配置过滤器,包括实例代码、YML配置以及JWT工具类的使用。同时,深入探讨了GlobalFilter、GatewayFilterChain以及Lambda表达式等核心原理,并涉及设计模式中的建设者模式。此外,文章还涵盖了Java8的新特性,如Lambda表达式、Optional操作和Stream流式处理。
摘要由CSDN通过智能技术生成

学习目标:

1.网关中配置过滤器实例
2.网关中配置过滤器原理
3.资料学习

学习内容:

1.实例中各部分方法的实际意义
2.原理来源于那些基础知识
3.java8新知识学习

学习产出:

1 网关中配置过滤器实例

1.1网关中配置过滤器java代码实现

import com.alibaba.fastjson.JSON;
import com.heima.admin.utils.AppJwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
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.Flux;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description:网关中配置过滤器
 * @Version: V1.0
 */
@Component
@Slf4j
@Order(0)  // 越小越优先执行
//GlobalFilter处理链接web请求
public class AuthorizeFilter implements GlobalFilter {
   

    List<String> urlList = Arrays.asList(
            "/v2/api-docs",
            "/login/in"
    );

    /**
     * GlobalFilter处理链接web请求的方法
     * @param exchange 服务交换(seesion)
     * @param chain 提供了一种委托给下一个筛选器的方法
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
   

        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        //1 判断用户是否登录
        //2 是登陆则放行
//        if (url.contains("/login/in")) {
   
//            return chain.filter(exchange);
//        }
        String url = request.getURI().getPath();
        for (String urls : urlList){
   
            //测试此字符串是否以指定的后缀结尾
            if (url.endsWith(urls)) {
   
                //调用网关过滤器
                return chain.filter(exchange);//放行
            }
        }

        //3 从 head 获取token
        String token = request.getHeaders().getFirst("token");
        //3.1 无 token 返回提示信息和401 拦截
        if (StringUtils.isBlank(token)) {
   
            //如果不存在,向客户端返回错误提示信息
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("host", request.getRemoteAddress().getHostName());
            resultMap.put("code", HttpStatus.UNAUTHORIZED.value());
            resultMap.put("errorMessage", "需要登录");

            return writeMessage(exchange, resultMap);
        }

        try {
   
            //3.2 有 token 校验token合法性, 无效则返回提示信息和401
            //获取payload body信息
            Claims claims = AppJwtUtil.getClaimsBody(token);
            //-1 0 -》有效     1 2  -》 无效
            //是否过期
            int verifyToken = AppJwtUtil.verifyToken(claims);
            if (verifyToken > 0) {
     // 无效  拦截
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("host", request.getRemoteAddress().getHostName());
                resultMap.put("code", HttpStatus.UNAUTHORIZED.value());
                resultMap.put("errorMessage", "登录已过期,请重新登录");

                return writeMessage(exchange, resultMap);
            }


            //4 有效:解析jwt令牌,获取的用户id  body信息就是token json形式信息
            Integer id = claims.get("id", Integer.class);

            //5 把用户的id 转发到各个微服务中
            //mutate变异,创建出ServerHttpRequest建设者-->建设者操纵请求头(加入userId)-->建设完成【这个和pojos类里面的建设者模式一样】
            ServerHttpRequest serverHttpRequest = request.mutate().headers(httpHeaders -> {
   
                httpHeaders.add("userId", String.valueOf(id));
            }).build();
            //服务交换给各个wei服务
            exchange.mutate().request(serverHttpRequest);

        } catch (Exception e) {
   
           // e.printStackTrace();
            // 记录日志
            log.error("jwt verifyToken is fail,url:{}", url);
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("host", request.getRemoteAddress().getHostName());
            resultMap.put("code", HttpStatus.UNAUTHORIZED.value()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_51297617

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值
>