SpringCloudGateway过滤器filter的使用


package com.gateway.config;


import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gateway.util.JWTConstant;
import com.gateway.util.JWTUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * GatewayFilter 用在单个路由上
 * GlobalFilter 用在整个网关之前
 */
@Component
public class LexueGatewayFilter implements GatewayFilter, Ordered {

    private static final Logger LOGGER = LoggerFactory.getLogger(LexueGatewayFilter.class);

    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {

 /*
       这个request对象可以获取更多的内容
      比如,如果是使用token验证的话,就可以判断它的Header中的Token值了
      为了演示方便,我就判断了它的参数
        */
//        ServerHttpRequest request = exchange.getRequest();
//        MultiValueMap queryParams = request.getQueryParams();
//        String username = queryParams.getFirst("username");
//        if (!username.equals("admin")) {

//            //不允许访问,禁止访问
//            ServerHttpResponse response = exchange.getResponse();
//            response.setStatusCode(HttpStatus.NOT_ACCEPTABLE); //这个状态码是406
//
//            return exchange.getResponse().setComplete();
//        }
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        InetSocketAddress addr = request.getRemoteAddress();
        System.out.println("当前访问的设备的 hostName :" + addr.getHostName());
        System.out.println("当前访问的设备的 address :" + addr.getAddress().toString());
        System.out.println("当前访问的设备的 port :" + addr.getPort());
        //TODO 如果是后台管理访问,放行
//        if(addr.getHostName().equals("220.113.124.160"))  return chain.filter(exchange);

        
        HttpHeaders headers = request.getHeaders();
        List strings = headers.get(JWTConstant.TOKEN_NAME);
        if(strings!=null){
            String lexueToken = strings.get(0);
            if(lexueToken!=null){
                try {
                    JWTUtils.verify(lexueToken);
                    //放行
                    return chain.filter(exchange);
                } catch (Exception e){
                    //只要有异常    就返回方法不允许
                    response.setStatusCode(HttpStatus.METHOD_NOT_ALLOWED);
                    //禁止访问
                    return exchange.getResponse().setComplete();
                }
            }else{
                //如果lexueToken==null 也不准访问
                return exchange.getResponse().setComplete();
            }
        }else {//没取到====告知前台,需要登录
            
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            //禁止访问
            return exchange.getResponse().setComplete();
        }
    }

    /**
     * 这是Ordered接口的中的方法
     * 过滤器有一个优先级的问题,这个值越小,优先级越高
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}
package com.gateway.config;

import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class LexueFilterConfiguration {

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(r ->
                        r.path("/api/lexueManager/courseselect/**",
                                "/api/lexueManager/note/**",
                                "/api/lexueManager/problem/**",
                                "/api/lexueManager/task/**",
                                "/api/lexueManager/user/list",
                                "/api/lexueManager/user/list",
                                "/api/lexueManager/user/info/**",
                                "/api/lexueManager/user/save",
                                "/api/lexueManager/user/update",
                                "/api/lexueManager/user/delete",
                                "/api/lexueManager/user/updatePassword",
                                "/api/lexueManager/usertask/**")
                                .filters(
                                        //指示在将请求发送到下游之前,要从请求中去除的路径中的节数
                                        f -> f.stripPrefix(1)
                                                .filters(new LexueGatewayFilter())
                                )
                                .uri("lb://lexueManager")
                )
                .build();


    }

}