Webflux 跨域設置及與權限沖突的解決辦法


網上提供了2種跨域的設置方式

  1為 重寫 WebFluxConfigurer 的 addCorsMappings。

  2為 提供一個 WebFilter 或 CorsWebFilter。

  注意點,如果有權限驗證的filter,建議使用第二種凡是,且CorsWebFilter一定要優先於AuthFilter過濾,否則跨域的PreFilght將一直失敗,無法實現跨域。

 

   Cors原理如下:

   瀏覽器將cors請求分為兩類即簡單請求和非簡單請求.
   簡單請求
   只要同時滿足以下條件就屬於簡單請求
   請求方法是以下三種方法之一:GET POST HEAD
   Http的頭信息不超出以下幾種字段:Accept Accept-Language Content-Language Last-Event-ID Content-Type 只限於三個值application/x-www-form-urlencoded、multipart/form-data、text/plain
   非簡單請求
   其他的請求皆屬於非簡單請求.
   注意在cors定義中,如果頭信息中的Content-Type不設置,則默認值為json/application,如果Content-Type值不為application/x-www-form-urlencoded,multipart/form-data或text/plain,都被視為非簡單請求,即預檢請求.

   瀏覽器對這兩種請求的處理是不一樣的.
   如果是簡單請求的話,一次完整的請求過程是不需要服務端預檢的,直接響應回客戶端。
   而非簡單請求則瀏覽器會在發送真正請求之前先用OPTIONS發送一次預檢請求preflight request,從而獲知服務端是否允許該跨域請求,當服務器確認允許之后,才會發起真正的請求.
 
   那么帶有權限的非簡單請求,首先要觸發了一次預檢請求,但由於服務端使用了權限認證框架,通過攔截用戶請求頭中傳過來的token信息來判定客戶端是否為非法調用,而Preflight請求過程中並不會攜帶我們自定義的token信息到服務器,這樣服務器校驗就永遠也無法通過了,就算是合法的登錄用戶也會被攔截.
 
  附:CorsWebFilter代碼
   
/**
 * 跨域Filter
 */
@Configuration
@Data
public class CorsFilter implements WebFluxConfigurer {

    @Value("#{'${cors.allowedOrigins:*}'.split(',')}")
    private List<String> allowedOrigins;
    @Value("#{'${cors.allowedHeaders:*}'.split(',')}")
    private List<String> allowedHeaders;
    @Value("#{'${cors.allowedMethods:*}'.split(',')}")
    private List<String> allowedMethods;
    @Value("${cors.corsMapping:/**}")
    private String corsMapping;

    /**
     * corsWebFilter需要早於AuthFiler
     */
    @Bean
    @Order(-200) //非常重要,一定要早於AuthFilter
    CorsWebFilter corsWebFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        for(String val:allowedOrigins){
            config.addAllowedOrigin(val);
        }
        for(String val:allowedHeaders){
            config.addAllowedHeader(val);
        }
        for(String val:allowedMethods){
            config.addAllowedMethod(val);
        }
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration(corsMapping, config);
        return new CorsWebFilter(source);
    }
}

  




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM