Tout le monde sait que Spring Boot peut réaliser des opérations inter-domaines via @CrossOrigin. Mais dans Spring Cloud, si vous souhaitez contrôler plusieurs domaines avec une granularité aussi fine, c'est trop lourd, donc d'une manière générale, cela sera implémenté dans le routage zuul.
Ajoutez un corsFilter sous le service zuul pour obtenir un cross-domain, ce qui est facile à mettre en œuvre. Le code est le suivant
@Configuration public class GateWayCorsConfig { @Bean public FilterRegistrationBean corsFilter() { final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); final CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin("*"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); //这个请求头在https中会出现,但是有点问题,下面我会说 //config.addExposedHeader("X-forwared-port, X-forwarded-host"); source.registerCorsConfiguration("/**", config); FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); bean.setOrder(Ordered.HIGHEST_PRECEDENCE); return bean; } }
Après tests, cette configuration est OK sur tous les domaines dans le cas de http, mais lorsque mon environnement passe en https, d'étranges problèmes surviennent. Expliquez le problème que j'ai rencontré. Le
Front-endService A et le Back-end Service B sont sur le même serveur lorsque le Service A appelle le Service B. , Lorsque le service A entre dans le service B via l'équilibrage de charge : lorsque
http est utilisé, la demande du service A réussit dans tous les domaines lorsque https l'est ; utilisé, service ALa requête a échoué sur tous les domaines.
C'est-à-dire que lorsque le port est 443, cela sera considéré comme un échec inter-domaines ! !
J'ai d'abord comparé les en-têtes de requête et j'ai pensé qu'il manquait le "X-forwared-port, X-forwarded-host" de ExposedHeader, mais après l'avoir ajouté, cela a toujours échoué. Parce que j'étais pressé d'aller en ligne, je n'ai pas effectué de test approfondi sur les causes de l'échec de la requête https entre domaines. (Donc, si vous trouvez quelque chose qui ne va pas dans ce que j'ai écrit, assurez-vous de m'en informer et de me faire comprendre pourquoi cela a échoué ! Merci !)
Parce que de la première façon Après avoir échoué sous https, j'ai essayé d'utiliser zuulfilter pour implémenter cors
Un total de deux filtres sont nécessaires : un pré, un post
Pré-filtre :
@Component public class FirstFilter extends ZuulFilter { private Logger logger = LoggerFactory.getLogger(FirstFilter.class); @Override public String filterType() { /* pre:可以在请求被路由之前调用 route:在路由请求时候被调用 post:在route和error过滤器之后被调用 error:处理请求时发生错误时被调用 * */ // 前置过滤器 return FilterConstants.PRE_TYPE; } @Override public int filterOrder() { //// 优先级为0,数字越大,优先级越低 return 0; } @Override public boolean shouldFilter() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); //只过滤OPTIONS 请求 if(request.getMethod().equals(RequestMethod.OPTIONS.name())){ return true; } return false; } @Override public Object run() { logger.debug("*****************FirstFilter run start*****************"); RequestContext ctx = RequestContext.getCurrentContext(); HttpServletResponse response = ctx.getResponse(); HttpServletRequest request = ctx.getRequest(); response.setHeader("Access-Control-Allow-Origin",request.getHeader("Origin")); response.setHeader("Access-Control-Allow-Credentials","true"); response.setHeader("Access-Control-Allow-Headers","authorization, content-type"); response.setHeader("Access-Control-Allow-Methods","POST,GET"); response.setHeader("Access-Control-Expose-Headers","X-forwared-port, X-forwarded-host"); response.setHeader("Vary","Origin,Access-Control-Request-Method,Access-Control-Request-Headers"); //不再路由 ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(200); logger.debug("*****************FirstFilter run end*****************"); return null; } }
Le pré-filtre est utilisé pour traiter les requêtes OPTIONS de pré-traitement Lorsqu'il s'avère qu'il s'agit d'une requête OPTIONS, un en-tête de réponse inter-domaines est donné, et il n'est pas acheminé par zuul et renvoie directement. success (200), permettant un service inter-domaines vers le service front-end
post-Filter :
@Component public class PostFilter extends ZuulFilter { private Logger logger = LoggerFactory.getLogger(PostFilter.class); @Override public String filterType() { /* pre:可以在请求被路由之前调用 route:在路由请求时候被调用 post:在route和error过滤器之后被调用 error:处理请求时发生错误时被调用 * */ // 前置过滤器 return FilterConstants.POST_TYPE; } @Override public int filterOrder() { //// 优先级为0,数字越大,优先级越低 return 2; } @Override public boolean shouldFilter() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); //过滤各种POST请求 if(request.getMethod().equals(RequestMethod.OPTIONS.name())){ return false; } return true; } @Override public Object run() { logger.debug("*****************PostFilter run start*****************"); RequestContext ctx = RequestContext.getCurrentContext(); HttpServletResponse response = ctx.getResponse(); HttpServletRequest request = ctx.getRequest(); response.setHeader("Access-Control-Allow-Origin",request.getHeader("Origin")); response.setHeader("Access-Control-Allow-Credentials","true"); response.setHeader("Access-Control-Expose-Headers","X-forwared-port, X-forwarded-host"); response.setHeader("Vary","Origin,Access-Control-Request-Method,Access-Control-Request-Headers"); //允许继续路由 ctx.setSendZuulResponse(true); ctx.setResponseStatusCode(200); logger.debug("*****************PostFilter run end*****************"); return null; } }
Post-Filter est utilisé pour traiter les requêtes autres que le prétraitement. OPTIONS. Pour les requêtes normales, non seulement les en-têtes de requête inter-domaines doivent être fournis, mais vous devez également autoriser le routage de la requête (sinon votre requête se terminera ici), puis renvoyer le code d'état 200. (emmmm... Je pense que je devrai peut-être réfléchir à l'opportunité de renvoyer 200 ici...)
S'ils sont configurés de la manière ci-dessus, les problèmes qui surviennent dans la méthode seront résolus. Le service A peut demander le service B normalement
Bien que les exigences aient été remplies normalement, j'ai toujours l'impression qu'il y a beaucoup de doutes. J'espère que si vous le voyez, vous pourrez me signaler les lacunes. Discutons-en ensemble !
Articles connexes :
Solution inter-domaines 1 : utilisez CORS pour implémenter cross-domain_html/css_WEB-ITnose
Utilisez CORS pour implémenter la méthode de requête inter-domaines WebApi Ajax
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!