Filter是gateway网关中提供的一种过滤器,可以提供对请求进行权限验证、请求前数据处理、请求后置处理等功能
在gateway网关中GlobalFilter(全局过滤器)和GatewayFilter(局部过滤器)
GlobalFilter是全局过滤器,针对的是全局请求过滤
@Slf4j
@Component
public class AuthFilter implements GlobalFilter, Ordered {
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String url = exchange.getRequest().getURI().getPath();
log.info("【网关】访问路径:{}", url);
List ignoreUrls = ignoreUrlProperties.getIgnoreUrls();
if (CollUtil.isNotEmpty(ignoreUrls) && ignoreUrls.contains(url)) {
return chain.filter(exchange);
}
String token = exchange.getRequest().getHeaders().getFirst(HeaderConst.X_ACCESS_TOKEN);
String customerId = change.getRequest().getHeaders().getFirst(HeaderConst.X_CUSTOMER_ID);
ServerHttpResponse response = exchange.getResponse();
if (!token.equals(redisToken)) {
return this.authFail(response);
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
//返回错误信息
private Mono authFail(ServerHttpResponse resp) {
resp.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
Map result = new HashMap<>();
result.put("code", 50001);
result.put("msg", "token错误,请重新登录");
result.put("desc", "操作失败");
result.put("data", new Object());
byte[] bytes = JSON.toJSONString(result).getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = resp.bufferFactory().wrap(bytes);
return resp.writeWith(Mono.just(buffer));
}
}
自定义GatewayFilter
GatewayFilter是局部过滤器,主要是根据配置到对应的网关路由配置中执行
@Slf4j @Component public class CommunityUserGatewayFilterFactory extends AbstractGatewayFilterFactory{ public static final String PREFIX_KEY = "communityUser"; private CommunityConsumer communityConsumer; private IgnoreUrlProperties ignoreUrlProperties; @Override public GatewayFilter apply(CommunityUserGatewayFilterFactory.Config config) { return new GatewayFilter() { public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { boolean alreadyPrefixed = (Boolean)exchange.getAttributeOrDefault(PREFIX_KEY, false); if (alreadyPrefixed) { return chain.filter(exchange); }else if(!Boolean.TRUE.toString().equalsIgnoreCase(config.communityUser)){ return chain.filter(exchange); } else { exchange.getAttributes().put(PREFIX_KEY, true); log.info("社区过滤器:{}",config.communityUser); String url=exchange.getRequest().getURI().getPath(); String customerId = exchange.getRequest().getHeaders().getFirst(HeaderConst.X_CUSTOMER_ID); if(!ignoreUrlProperties.getCommunityUser().contains(url)){ return chain.filter(exchange); } HttpResult httpResult=communityConsumer.isBan(Long.valueOf(customerId)); if(httpResult==null||httpResult.getCode()!= DefaultHttpResultStatus.SUCCESS.getCode()||httpResult.getData()==null){ return authFail(exchange.getResponse(),50000,"请稍候重试"); } if(httpResult.getData()){ return authFail(exchange.getResponse(),60000,"禁言中"); } return chain.filter(exchange); } } }; } public CommunityUserGatewayFilterFactory() { super(CommunityUserGatewayFilterFactory.Config.class); } @Override public List shortcutFieldOrder() { return Arrays.asList("communityUser"); } @Lazy @Autowired public void setCommunityConsumer(CommunityConsumer communityConsumer) { this.communityConsumer = communityConsumer; } @Autowired public void setIgnoreUrlProperties(IgnoreUrlProperties ignoreUrlProperties) { this.ignoreUrlProperties = ignoreUrlProperties; } public static class Config { private String communityUser; public Config() { } public String getCommunityUser() { return communityUser; } public void setCommunityUser(String communityUser) { this.communityUser = communityUser; } } private Mono authFail(ServerHttpResponse resp,Integer code,String message) { resp.getHeaders().add("Content-Type", "application/json;charset=UTF-8"); Map result = new HashMap<>(); result.put("code", code); result.put("msg", message); result.put("desc", message); result.put("data", new Object()); byte[] bytes = JSON.toJSONString(result).getBytes(StandardCharsets.UTF_8); DataBuffer buffer = resp.bufferFactory().wrap(bytes); return resp.writeWith(Mono.just(buffer)); } }
代码写完了怎么使用:
spring:
application:
name: xxxx-tsp-gateway-app
cloud:
gateway:
discovery:
locator:
enabled: true
routes:
- id: service-community
uri: lb://xxxxxx-tsp-service-community
predicates:
- Path=/app/community/**
filters:
- StripPrefix=1
- CommunityUser=true
注意:自定义的GatewayFilter类名必须是GatewayFilterFactory结尾;
使用的是直接使用文件名GatewayFilterFactory前面的即可
bean必须放入Spring容器中
shortcutFieldOrder方法必须重写
@Component
public class CommunityUserInterceptor implements HandlerInterceptor {
private ICommunityUserService iCommunityUserService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String customerId=request.getHeader(HeaderConst.X_CUSTOMER_ID);
if(StringUtils.isEmpty(customerId)){
return true;
}
if(iCommunityUserService.isBan(Long.parseLong(customerId))){
throw new BanException("禁言中");
}
return false;
}
@Autowired
public void setiCommunityUserService(ICommunityUserService iCommunityUserService) {
this.iCommunityUserService = iCommunityUserService;
}
}
配置mvc拦截器,添加自定义拦截器
@Configuration
public class MyWebAppConfigurer implements WebMvcConfigurer {
private CommunityUserInterceptor communityUserInterceptor;
private BanUrlProperties banUrlProperties;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(communityUserInterceptor).addPathPatterns(banUrlProperties.getUrls());
}
@Autowired
public void setCommunityUserInterceptor(CommunityUserInterceptor communityUserInterceptor) {
this.communityUserInterceptor = communityUserInterceptor;
}
@Autowired
public void setBanUrlProperties(BanUrlProperties banUrlProperties) {
this.banUrlProperties = banUrlProperties;
}
}
获取定义的拦截地址
@Data
@RefreshScope
@Configuration
@ConfigurationProperties(prefix = "ban")
public class BanUrlProperties {
private List urls;
}



