| package com.doumee.config; | 
|   | 
| import com.doumee.core.utils.Constants; | 
| import org.apache.commons.lang3.StringUtils; | 
| import org.springframework.beans.factory.annotation.Autowired; | 
| import org.springframework.cloud.gateway.filter.GatewayFilterChain; | 
| import org.springframework.cloud.gateway.filter.GlobalFilter; | 
| import org.springframework.context.annotation.Configuration; | 
| import org.springframework.core.annotation.Order; | 
| import org.springframework.data.redis.core.RedisTemplate; | 
| import org.springframework.http.HttpStatus; | 
| import org.springframework.http.MediaType; | 
| import org.springframework.http.server.reactive.ServerHttpRequest; | 
| import org.springframework.stereotype.Component; | 
| import org.springframework.util.AntPathMatcher; | 
| import org.springframework.util.PathMatcher; | 
| import org.springframework.web.server.ServerWebExchange; | 
| import reactor.core.publisher.Mono; | 
|   | 
| import javax.annotation.Resource; | 
|   | 
| //@Order(1) | 
| //@Configuration | 
| public class GlobalFilterConfig implements GlobalFilter { | 
|     @Autowired | 
|     private RedisTemplate<String,Object> stringRedisTemplate; | 
|   | 
|     @Resource | 
|     private GatewayFilterProperties notAuthUrlProperties; | 
|   | 
|     @Override | 
|     public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { | 
|            /* log.info("================================================="); | 
|             log.info("访问接口主机: {}", exchange.getRequest().getURI().getHost()); | 
|             log.info("访问接口端口: {}", exchange.getRequest().getURI().getPort()); | 
|             log.info("访问接口URL: {}", exchange.getRequest().getURI().getPath()); | 
|             log.info("访问接口参数: {}", exchange.getRequest().getURI().getRawQuery());*/ | 
|         String  url =exchange.getRequest().getURI().getPath(); | 
|         if(!shouldSkip(url)){ | 
|             String token = exchange.getRequest().getHeaders().getFirst(Constants.HEADER_USER_TOKEN); | 
|             if (token == null || token.isEmpty()) { | 
|                 return unAuthorize(exchange); | 
|   | 
|             } | 
|             String userInfo =(String) stringRedisTemplate.opsForValue().get(Constants.REDIS_TOKEN_KEY + token); | 
|             if (StringUtils.isBlank(userInfo)) { | 
|                 return unAuthorize(exchange); | 
|             } | 
|             //把新的 exchange放回到过滤链 | 
|             ServerHttpRequest request = exchange.getRequest().mutate().header(Constants.HEADER_USER_TOKEN, token).build(); | 
|             ServerWebExchange newExchange = exchange.mutate().request(request).build(); | 
|             return chain.filter(newExchange); | 
|         } | 
|         return chain.filter(exchange); | 
|     } | 
|     /** | 
|      * 方法实现说明:不需要过滤的路径 | 
|      * <p> | 
|      * //     * @param currentUrl 当前请求路径 | 
|      */ | 
|     private boolean shouldSkip(String currentUrl) { | 
|         if(notAuthUrlProperties.getSkipLoginFilterUrls() == null || notAuthUrlProperties.getSkipLoginFilterUrls().size() ==0){ | 
|             return  false; | 
|         } | 
|         PathMatcher pathMatcher = new AntPathMatcher(); | 
|         for (String skipPath : notAuthUrlProperties.getSkipLoginFilterUrls()) { | 
|             if (pathMatcher.match(skipPath, currentUrl)) { | 
|                 return true; | 
|             } | 
|         } | 
|         return false; | 
|     } | 
|   | 
|     // 返回未登录的自定义错误 | 
|     private Mono<Void> unAuthorize(ServerWebExchange exchange) { | 
|         // 设置错误状态码为401 | 
|         exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); | 
|         // 设置返回的信息为JSON类型 | 
|         exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON); | 
|         // 自定义错误信息 | 
|         String errorMsg = "{\"error\": \"" + "用户未登录或登录超时,请重新登录" + "\"}"; | 
|         // 将自定义错误响应写入响应体 | 
|         return exchange.getResponse() | 
|                 .writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(errorMsg.getBytes()))); | 
|     } | 
| } |