spring cloud zuul網關的做用

zuul通常有兩大做用,1是相似於Nginx的網址重定向,但zuul的重定向的通常是整個spring cloud裏在Eureka註冊中心的模塊.spring

zuul:
  ignored-services: '*'
  sensitiveHeaders: Access-Control-Allow-Origin
  ignored-headers: Access-Control-Allow-Credentials,Access-Control-Allow-Origin,Vary,X-Frame-Options,token
  routes:
    oauth:
      path: /api-o/**
      serviceId: oauth-center
    api-u:
      path: /api-u/**
      serviceId: user-center
    backend:
      path: /api-b/**
      serviceId: manage-backend
    log:
      path: /api-l/**
      serviceId: log-center
    file:
      path: /api-f/**
      serviceId: file-center
    sms:
      path: /api-n/**
      serviceId: notification-center

**的意思是能夠匹配任何多級目錄的意思.api

*爲單級目錄跨域

sensitiveHeaders過濾客戶端附帶的headers,如:緩存

sensitiveHeaders: X-ABC
若是在發請求時帶了X-ABC,那麼X-ABC不會往下游服務傳遞。此處爲禁止跨域請求頭向下傳遞服務器

ignored-headers會過濾服務之間通訊附帶的headerscookie

附帶服務的跨域配置app

/**
 * 跨域配置
 */
@Configuration
public class CrossDomainConfig {

    /**
     * 跨域支持
     *
     * @return
     */
    @Bean
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true); // 容許cookies跨域
        config.addAllowedOrigin("*");// #容許向該服務器提交請求的URI,*表示所有容許
        config.addAllowedHeader("*");// #容許訪問的頭信息,*表示所有
        config.setMaxAge(18000L);// 預檢請求的緩存時間(秒),即在這個時間段裏,對於相同的跨域請求不會再預檢了
        config.addAllowedMethod("*");// 容許提交請求的方法,*表示所有容許
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

二、zuul更重要的功能爲過濾請求.cors

public class AccessFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return null;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return false;
    }

    @Override
    public Object run() throws ZuulException {
        return null;
    }
}

咱們自定義一個過濾類,繼承於ZuulFilter,通常要實現上面四個方法.ide

filterType:過濾器的類型.微服務

  • pre:能夠在請求被路由以前調用
  • route:在路由請求時候被調用
  • post:在route和error過濾器以後被調用
  • error:處理請求時發生錯誤時被調用

org.springframework.cloud.netflix.zuul.filters.support.FilterConstants

中有這四種對應

public static final String ERROR_TYPE = "error";
public static final String POST_TYPE = "post";
public static final String PRE_TYPE = "pre";
public static final String ROUTE_TYPE = "route";

filterOrder:過濾器的執行順序.當請求在一個階段存在多個過濾器時,須要根據該方法返回的值來依次執行.

shouldFilter:判斷該過濾器是否須要執行.

好比咱們須要一個過濾條件,當包含"*-anon/internal*"的uri不容許外網經過網關調用,只容許微服務間在內網調用.咱們能夠這麼寫.

@Override
public boolean shouldFilter() {
   RequestContext requestContext = RequestContext.getCurrentContext();
   HttpServletRequest request = requestContext.getRequest();

   return PatternMatchUtils.simpleMatch("*-anon/internal*", request.getRequestURI());
}

最後就是run:過濾器的具體邏輯.

@Override
public Object run() {
   RequestContext requestContext = RequestContext.getCurrentContext();
   requestContext.setResponseStatusCode(HttpStatus.FORBIDDEN.value());
   requestContext.setResponseBody(HttpStatus.FORBIDDEN.getReasonPhrase());
   requestContext.setSendZuulResponse(false);

   return null;
}

返回403 Forbidden錯誤,經過requestContext.setSendZuulResponse(false)不進行路由.

請注意以上是隻防外網的,內網的調用可使用feign.好比說

@FeignClient("manage-backend")
public interface BackendClient {

   @GetMapping("/backend-anon/internal/blackIPs")
   Set<String> findAllBlackIPs(@RequestParam("params") Map<String, Object> params);
}

它是指向manage-backend模塊的,並且@GetMapping("/backend-anon/internal/blackIPs")包含了"*-anon/internal*",即外網沒法訪問這個接口.具體實現爲

@RestController
public class BlackIPController {

   @Autowired
   private BlackIPService blackIPService;

   /**
    * 添加黑名單ip
    * 
    * @param ip
    */
   @LogAnnotation(module = LogModule.ADD_BLACK_IP)
   @PreAuthorize("hasAuthority('ip:black:save')")
   @PostMapping("/blackIPs")
   public void save(@RequestBody BlackIP blackIP) {
      blackIP.setCreateTime(new Date());

      blackIPService.save(blackIP);
   }

   /**
    * 刪除黑名單ip
    * 
    * @param ip
    */
   @LogAnnotation(module = LogModule.DELETE_BLACK_IP)
   @PreAuthorize("hasAuthority('ip:black:delete')")
   @DeleteMapping("/blackIPs/{ip}")
   public void delete(@PathVariable String ip) {
      blackIPService.delete(ip);
   }

   /**
    * 查詢黑名單
    * 
    * @param params
    * @return
    */
   @PreAuthorize("hasAuthority('ip:black:query')")
   @GetMapping("/blackIPs")
   public Page<BlackIP> findBlackIPs(@RequestParam Map<String, Object> params) {
      return blackIPService.findBlackIPs(params);
   }

   /**
    * 查詢黑名單<br>
    * 可內網匿名訪問
    * 
    * @param params
    * @return
    */
   @GetMapping("/backend-anon/internal/blackIPs")
   public Set<String> findAllBlackIPs(@RequestParam Map<String, Object> params) {
      Page<BlackIP> page = blackIPService.findBlackIPs(params);
      if (page.getTotal() > 0) {
         return page.getData().stream().map(BlackIP::getIp).collect(Collectors.toSet());
      }
      return Collections.emptySet();
   }
}

中的

@GetMapping("/backend-anon/internal/blackIPs")
public Set<String> findAllBlackIPs(@RequestParam Map<String, Object> params) {
   Page<BlackIP> page = blackIPService.findBlackIPs(params);
   if (page.getTotal() > 0) {
      return page.getData().stream().map(BlackIP::getIp).collect(Collectors.toSet());
   }
   return Collections.emptySet();
}

固然它是屬於manage-backend模塊.

相關文章
相關標籤/搜索