基于Eureka的网关服务(gateway)配置

在做项目的时候,用户身份认证最开始用的是web拦截器来实现的,原理很简单,可以参考这篇文章:springboot拦截器配置_酷乐丶是只猫的博客-CSDN博客

使用Eureka后可以将用户身份认证功能单独从项目中抽取出来,成为一个独立的模块,降低了项目的耦合性,同时也方便其他项目访问该功能。

1.Eureka服务中心部署

搭建Eureka项目首先需要搭建一个服务中心,服务中心相当于一个中转站,其中包含了各种服务,服务之间可以相互访问。

首先新建一个spring项目

服务器中心的pom.xml依赖如下(注意spring cloud与springboot的版本对应关系,如果springboot版本过高或者过低,都需要调整spring cloud的版本,这里用的springboot的版本是2.6.1,对应的spring cloud版本是2021.0.0):


        1.8
        2021.0.0
    
    
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-server
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    
    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                ${spring-cloud.version}
                pom
                import
            
        
    

 接着再配置一下yml文件。

eureka.client.registerWithEureka 表示是否将自己注册到Eureka服务中心,因为其本身就是个服务中心,因此设为false。
eureka.client.fetchRegistry 表示是否从Eureka服务中心获取注册信息,同样也是设为false。
eureka.client.serviceUrl.defaultZone :设置与Eureka服务中心交互地址,查询服务和注册服务都需要依赖这个地址。

server:
  port: 8761

eureka:
  instance:
    hostname: localhost
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

然后配置下spring启动类,添加一个@EnableEurekaServer注解即可:

@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }

}

2.网关服务部署

部署完服务中心后,需要将网关服务注册进服务中心,这里用到的是spring cloud gateway。

同样先新建一个spring项目。

pom.xml依赖如下



        
            org.projectlombok
            lombok
            provided
        


        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
        
        
        
            org.springframework.boot
            spring-boot-starter-actuator
        
        
        
            org.springframework.cloud
            spring-cloud-starter-gateway
        
        
            org.apache.commons
            commons-lang3
        

        
        
            io.jsonwebtoken
            jjwt-api
            ${jwt.version}
        
        
            io.jsonwebtoken
            jjwt-impl
            ${jwt.version}
            runtime
        
        
            io.jsonwebtoken
            jjwt-jackson
            ${jwt.version}
            runtime
        
        
            com.alibaba
            fastjson
            1.2.60
        

    
    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                ${spring-cloud.version}
                pom
                import
            
        
    

接着配置yml文件,这里配置了gateway的属性,discovery开启服务注册中心服务发现,routes为网关路由配置,当通过网关认证时,页面会跳转到url中的路径;predicates则会对匹配的请求进行过滤验证;filters为过滤器配置,JwtAuthorization为过滤器名字:

server:
  port: 8877

spring:
  application:
    name: microservice-eureka-user
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启 Gateway 服务注册中心服务发现
          lower-case-service-id: true
      routes:
        - id: api
          uri: http://localhost:8888
          predicates:
            - Path=/api/**
          filters:
            - StripPrefix=0
            - JwtAuthorization



eureka:
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
    ip-address: ${spring.cloud.client.ip-address}
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka
    healthcheck:
      enabled: true

filter工厂配置:

@Component
public class JwtAuthorizationGatewayFilterFactory extends AbstractGatewayFilterFactory {
    @Override
    public GatewayFilter apply(Object config) {
        return new JwtAuthorizationFilter();
    }
} 
  

filter配置:

@Component
public class JwtAuthorizationFilter implements GatewayFilter, Ordered {


    List ignoreList = Arrays.asList("/api/loginPage/login");

    /**
     * 该值要和auth-server中配置的签名相同
     * 

* com.kdyzm.spring.security.auth.center.config.TokenConfig#SIGNING_KEY */ private ObjectMapper objectMapper = new ObjectMapper(); @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { boolean access = true; ServerHttpRequest serverReques = exchange.getRequest(); // 将Payload数据放到header ServerHttpRequest.Builder builder = serverReques.mutate(); if(!access){ return unAuthorized(exchange,"认证不通过",null); } // 继续执行 return chain.filter(exchange.mutate().request(builder.build()).build()); } private Mono unAuthorized(ServerWebExchange exchange, String msg,Integer status) { try { exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); //这里需要指定响应头部信息,否则会中文乱码 exchange.getResponse().getHeaders().add("Content-Type", "application/json;charset=UTF-8"); JSONObject ret=new JSONObject(); if(Objects.isNull(status)) { ret.put("code", 401); ret.put("message", msg); ret.put("data",null); }else{ ret.put("code", status); ret.put("message", msg); ret.put("data",null); } String s = objectMapper.writeValueAsString(ret); DataBuffer buffer = exchange .getResponse() .bufferFactory() .wrap(s.getBytes(StandardCharsets.UTF_8)); return exchange.getResponse().writeWith(Flux.just(buffer)); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 将该过滤器的优先级设置为最高,因为只要认证不通过,就不能做任何事情 * * @return */ @Override public int getOrder() { return Ordered.HIGHEST_PRECEDENCE; } }

当请求进行过滤时会先进入filter方法,该方法可以设置一些请求认证的功能,当请求通过认证时,返回chain.filter继续执行,否则返回unAuthorized方法拒绝通过网关。

你可能感兴趣的:(springboot,eureka,spring,boot,spring,cloud)