学习目标:
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()

本文介绍了如何在Spring Cloud Gateway中配置过滤器,包括实例代码、YML配置以及JWT工具类的使用。同时,深入探讨了GlobalFilter、GatewayFilterChain以及Lambda表达式等核心原理,并涉及设计模式中的建设者模式。此外,文章还涵盖了Java8的新特性,如Lambda表达式、Optional操作和Stream流式处理。
最低0.47元/天 解锁文章
1369

被折叠的 条评论
为什么被折叠?



