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模塊.