ドメイン間:ドメイン間の一般的なソリューションの概要


ドメイン間:ドメイン間の一般的なソリューションの概要
  • 『ドメイン間:「ドメイン間」の概念と原因を簡単に述べる』
  • 『ドメイン間:ドメイン間の概要』
  • セキュリティ上の理由から、ブラウザは現在のソース以外に存在するリソースのAJAX呼び出しを禁止します.
    ソース間リソース共有(CORS)は、ほとんどのブラウザで実装されているW 3 C仕様であり、IframeやJSONPなどのセキュリティが低く、機能が弱いハッカーではなく、許可されたドメイン間リクエストタイプを柔軟に指定することができます.
    方法1:@CorsConfigurationを使用する
    /**
     * 
     *           
     */
    @Configuration
    public class CorsConfig {
        private CorsConfiguration buildConfig() {
            CorsConfiguration corsConfiguration = new CorsConfiguration();
            	// 1.        
            	corsConfiguration.addAllowedOrigin("*"); 
            	// 2.         
            	corsConfiguration.addAllowedHeader("*"); 
            	 // 3.          
            	corsConfiguration.addAllowedMethod("*");
            
            return corsConfiguration;
        }
    
        @Bean
        public CorsFilter corsFilter() {
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            	// 4.          
            	source.registerCorsConfiguration("/**", buildConfig()); 
            	
            return new CorsFilter(source);
        }
    }
    

    上記のコードでは、「*」はすべてを表します.**すべてのインタフェースに適していることを示します.
    ここでaddAllowedOrigin(String origin)メソッドは、ソースアドレスへの追加アクセスです.「*」を使用しない場合(すべてのソースへのアクセスが許可されます)、複数のアクセスソースを構成して制御できます.例:
    corsConfiguration.addAllowedOrigin("http://www.a.cn/"); 
    corsConfiguration.addAllowedOrigin("http://test.b.cn/"); 
    

    CorsConfigurationクラスの公式ドキュメントにはaddAllowedOrigin(String origin)メソッドのほか、setAllowedOrigins(List allowedOrigins)メソッドがあり、以下のように実現されています.
    public void setAllowedOrigins(List allowedOrigins) {
    	this.allowedOrigins = allowedOrigins != null?new ArrayList(allowedOrigins):null;
    }
    

    addAllowedOriginは追加アクセスソースアドレスであり、setAllowedOriginsは複数のアクセスソースを直接設定することができる.上記のソースコードから、setAllowedOriginsはthis.allowedOriginsを上書きすることがわかります.したがって、アクセス元アドレスを構成する場合、addAllowedOriginメソッドはsetAllowedOriginsの後に書きます.もちろん、一般的にはこの2つのメソッドを混在させることはお勧めしません.
    addAllowedHeader、addAllowedMethod、registerCorsConfigurationメソッドとaddAllowedOriginのソースコードは似ていますが、ここでは一つ一つ説明しません.
    方法2:WebMvcConfigurerを使用する
    @Configuration
    public class MyConfiguration {
    
        @Bean
        public WebMvcConfigurer corsConfigurer() {
            return new WebMvcConfigurerAdapter() {
                @Override
                public void addCorsMappings(CorsRegistry registry) {
                    //registry.addMapping("/**");
                    registry.addMapping("/api/**")
    					    .allowedOrigins("http://domain2.com")
    						.allowedMethods("PUT", "DELETE")
    						.allowedHeaders("header1", "header2", "header3")
    						.exposedHeaders("header1", "header2")
    						.allowCredentials(false).maxAge(3600);
                }
            };
        }
    }
    
    @Configuration
    class CORSConfiguration implements WebMvcConfigurer {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            //registry.addMapping("/**");
            registry.addMapping("/api/**")
                .allowedOrigins("http://domain2.com")
                .allowedMethods("PUT", "DELETE")
                .allowedHeaders("header1", "header2", "header3")
                .exposedHeaders("header1", "header2")
                .allowCredentials(false).maxAge(3600);
        }
    }
    

    方法3、@CrossOrgin注釈を使う
    @CrossOrgin注記は、メソッドにもControllerレイヤ全体にも使用できます.
    コントローラとメソッドにCORS構成がある場合、Springは2つのアノテーション属性を組み合わせて、マージされたCORS構成を作成します.
  • Controllerレイヤ全体で@CrossOrgin注記構成
  • を使用
    @CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
    @RestController
    @RequestMapping("/account")
    public class AccountController {
    
    	@GetMapping("/{id}")
    	public Account retrieve(@PathVariable Long id) {
    		// ...
    	}
    
    	@DeleteMapping("/{id}")
    	public void remove(@PathVariable Long id) {
    		// ...
    	}
    }
    
  • Controllerレイヤでのメソッド@CrossOrgin注記構成
  • を使用
    @RestController
    @RequestMapping("/account")
    public class AccountController {
    
    	@CrossOrigin
    	@GetMapping("/{id}")
    	public Account retrieve(@PathVariable Long id) {
    		// ...
    	}
    
    	@DeleteMapping("/{id}")
    	public void remove(@PathVariable Long id) {
    		// ...
    	}
    }
    
  • Controllerレイヤコントローラとメソッドの両方で@CrossOrgin注記構成
  • を使用
    @CrossOrigin(maxAge = 3600)
    @RestController
    @RequestMapping("/account")
    public class AccountController {
    
    	@CrossOrigin(origins = "http://domain2.com")
    	@GetMapping("/{id}")
    	public Account retrieve(@PathVariable Long id) {
    		// ...
    	}
    
    	@DeleteMapping("/{id}")
    	public void remove(@PathVariable Long id) {
    		// ...
    	}
    }
    

    Spring Securityを使用している場合は、Spring SecurityレベルでCORSが有効になっていることを確認し、Spring MVCレベルで定義された構成を使用できるようにする必要があります.
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
    	@Override
    	protected void configure(HttpSecurity http) throws Exception {
    		http.cors().and()...
    	}
    }
    

    方法四、Filterを使用してHeaderを構成する
    @Component
    public class CORSFilter implements Filter {
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            HttpServletResponse res = (HttpServletResponse) response;
            res.addHeader("Access-Control-Allow-Credentials", "true");
            res.addHeader("Access-Control-Allow-Origin", "*");
            res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
            res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN");
            
            if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) {
                response.getWriter().println("ok");
                return;
            }
            
            chain.doFilter(request, response);
        }
        
        @Override
        public void destroy() {
        }
        
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
    }
    

    方法五、Nginx構成の使用
    プロジェクトでNginxを使用すると、Nginxに次の構成を追加してドメイン間(原理はFilterと似ています)を解決できます.
    location / {
       add_header Access-Control-Allow-Origin *;
       add_header Access-Control-Allow-Headers X-Requested-With;
       add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
    
       if ($request_method = 'OPTIONS') {
         return 204;
       }
    }