微服务跨域问题和过滤器代码

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_45042013/article/details/102642056

问题的出现:两个域名不同(端口不同)之间,发送ajax异步请求,浏览器认为这是危险的,从而有了跨域问题

目前比较常用的跨域解决方案有3种:

  • Jsonp

    最早的解决方案,利用script标签可以跨域的原理实现。

    限制:

    • 需要服务的支持
    • 只能发起GET请求
  • nginx反向代理

    思路是:利用nginx反向代理把跨域为不跨域,支持各种请求方式

    缺点:需要在nginx进行额外配置,语义不清晰

  • CORS

    规范化的跨域请求解决方案,安全可靠。

    优势:

    • 在服务端进行控制是否允许跨域,可自定义规则
    • 支持各种请求方式

    缺点:

    • 会产生额外的请求
      cors解决方法: —— 浏览器将ajax请求分为两类
      - 简单请求
      head、get、post
      这时浏览器请求头中会携带origin字段,指出请求属于哪个域(协议+域名+端口)
      响应头里含有以下两个信息,便能实现跨域请求
      Assess-Controller-Allow-Origin:可以接受的域
      Assess-Controller-Allow-Credentials:是否允许写带cookie信息
      - 特殊请求
      如put请求
      这时浏览器会执行预检,在简单请求的请求头基础上再增加两个字段分别是
      Assess-Controller-Request-Methods:请求方法
      Assess-Controller-Request-Headers:额外的请求头信息
      若响应头有如下信息,便能执行跨域请求
      Assess-Controller-Allow-Origin 允许的域
      Assess-Controller-Allow-Credentials 是否发送cookie
      Assess-Controller-Allow-Methods:允许的方法
      Assess-Controller-Allow-Headers:允许携带的头信息
      Assess-Controller-Max-Age:本次许可时间

cors跨域过滤器代码如下:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
 * 跨域过滤器
 */
@Configuration  // 启动容器加载bean
public class GlobalCorsConfig {

    @Bean
    public CorsFilter corsFilter(){
        // 1.添加CORS配置信息
        CorsConfiguration config = new CorsConfiguration();

         // 1.1 允许通过的域 ,不要写*,否则cookie无法使用
        config.addAllowedOrigin("http://manage.111.com");
        config.addAllowedOrigin("http://api.l111.com");
        config.addAllowedOrigin("http://www.111.com");
        config.addAllowedOrigin("http://image.111.com");

        // 1.2是否发送cookie信息
        config.setAllowCredentials(true);

        // 1.3 允许通过的请求方式
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("HEAD");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("DELETE");

        // 1.4 允许通过的请求头信息
        config.addAllowedHeader("*");
        // 1.5 有效时间
        config.setMaxAge(360000L);

        // 2.添加映射路径,拦截一切请求
        UrlBasedCorsConfigurationSource configurationSource = new UrlBasedCorsConfigurationSource();
        configurationSource.registerCorsConfiguration("/**",config);

        // 3.返回新的资源CorsFilter
        return new CorsFilter(configurationSource);
    }

}

方便维护过滤器配置代码:(推荐使用)

/**
 * 网关
 */
//@SpringBootApplication
//@EnableDiscoveryClient
@SpringCloudApplication
@EnableZuulProxy  // 声明是一个网关启动类
@EnableConfigurationProperties(CORSProperties.class)
public class lyGateway {
    public static void main(String[] args) {
        SpringApplication.run(lyGateway.class,args);
    }
}
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.List;

/**
 * 跨域资源实体类
 */
@Data
@ConfigurationProperties(prefix = "ly.cors")
public class CORSProperties {

    private List<String> allowedOrigins; //允许通过的域
    private Boolean allowedCredentials; // 是否发送cookie信息
    private List<String> allowedMethods; // 允许通过的请求方式
    private List<String> allowedHeaders; // 允许通过的请求头信息
    private Long maxAge;  // 有效时间
    private String filterPath; // 添加映射路径,拦截一切请求
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
 * 跨域过滤器
 */
@Configuration  // 声明是一个配置,启动容器加载bean
public class GlobalCorsConfig {
    

   @Autowired
   private CORSProperties prop;

    /**
     * @bean 自动执行当前方法,而且会把方法放入IOC容器中
     *  如果当前方法有参数,会自动去IOC容器中寻找同类型的对象,作为参数使用
     * @return
     */
    @Bean
    public CorsFilter corsFilter() {
        //1.添加CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
        //1) 允许的域,不要写*,否则cookie就无法使用了
        prop.getAllowedOrigins().forEach(config::addAllowedOrigin);
        //2) 是否发送Cookie信息
        config.setAllowCredentials(prop.getAllowedCredentials());
        //3) 允许的请求方式
        prop.getAllowedMethods().forEach(config::addAllowedMethod);
        // 4)允许的头信息
        prop.getAllowedHeaders().forEach(config::addAllowedHeader);
        // 5)配置有效期
        config.setMaxAge(prop.getMaxAge());

        //2.添加映射路径,拦截一切请求
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration(prop.getFilterPath(), config);

        //3.返回新的CORSFilter.
        return new CorsFilter(configSource);
    }

}

# 跨域过滤器
ly:
  cors:
    allowedOrigins:
      - http://manage.111.com
      - http://api.111.com
      - http://www.111.com
      - http://image.111.com
    allowedCredentials: true
    allowedHeaders:
      - "*"
    allowedMethods:
      - GET
      - POST
      - DELETE
      - PUT
      - OPTIONS
      - HEAD
    maxAge: 360000
    filterPath: "/**"

猜你喜欢

转载自blog.csdn.net/qq_45042013/article/details/102642056
今日推荐