簡體   English   中英

由於 CORS ZC5FD214CDD0D2B3B422Z2E73B022BA5C,無法使 Spring 引導 API 請求

[英]Unable To Make Spring Boot API Request Due To CORS Docker

我有一個 React 前端應用程序,它對 Spring 啟動應用程序進行 API 調用。

兩者都在單獨的 docker 容器中。 當它在本地運行時,一切都很好,但是在部署之后,當調用時,我得到一個 CORS 錯誤:

Access to fetch at 'http://xx.xx.xxx.xx:8080/simulations/1/ratings/1' from origin 'http://xx.xx.xxx.xx:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

我不確定為什么會這樣。 在我看來,我已經編寫了所有代碼以允許 CORS 訪問(正如我所說它在本地工作,所以我不明白為什么它在部署后失敗。我已經閱讀了一些關於 docker 和 localhost 的信息,但它看起來很混亂對我來說。

這是我來自WebSecurityConfigurerAdapter的 Java 安全代碼:

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("http://xx.xx.xxx.xx:3000"));
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

docker-compose.yml如下:

version: '3'
services:     
  application-server:
    restart: always
    image: 'myhub/app-server:cors'
    expose:
      - '8080'
    ports:
      - '8080:8080'
    networks:
      - local      
  application-client:
    restart: always
    image: 'myhub/app-client:cors'
    ports:
      - '3000:80'
    stdin_open: true
    depends_on:
      - application-server
    networks:
      - local
networks: 
  local:
    driver: bridge      

最后是nginx.conf

http
{
  server_tokens off;
  include /etc/nginx/mime.types;
  default_type application/octet-stream;

  upstream backend
  {
    server xx.xx.xxx.xx:8080;
  }

  server
  {

    listen 80;
    server_name localhost;

    access_log /var/log/nginx/host.access.log;
    error_log /var/log/nginx/host.error.log;


    root /var/www;
    index index.html index.htm;

    location ~* \.(?:manifest|appcache|html?|xml|json)$
    {
      expires -1;
    }

    location ~* \.(?:css|js)$
    {
      try_files $uri =404;
      expires 1y;
      access_log off;
      add_header Cache-Control "public";
    }

    # Any route containing a file extension (e.g. /devicesfile.js)
    location ~ ^.+\..+$
    {
      try_files $uri =404;
    }

    location /
    {

      root /var/www;
      index index.html;
      autoindex on;
      set $fallback_file /index.html;
      if ($http_accept !~ text/html)
      {
        set $fallback_file /null;
      }
      if ($uri ~ /$)
      {
        set $fallback_file /null;
      }
      try_files $uri $fallback_file;

      if ($request_method = 'OPTIONS')
      {
        add_header 'Access-Control-Allow-Origin: $http_origin');
        add_header 'Access-Control-Allow-Origin: GET, POST, DELETE, PUT, PATCH, OPTIONS');
        add_header 'Access-Control-Allow-Credentials: true');
        add_header 'Vary: Origin');

      }

      add_header 'Access-Control-Allow-Origin' "$http_origin" always;
      add_header 'Access-Control-Allow-Credentials' 'true' always;
      add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE, OPTIONS' always;
      add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;

    }
  }
}

我需要對容器做什么才能允許 CORS 訪問?

第一:要從 CORS 中受益,您無需關注 http 客戶端配置。
只有回答以下問題的后端才允許授權:該主機、端口、請求是否可接受? 與需要配置客戶端和服務器的 CSRF 相反。

我提到這一點,因為您公開了您的客戶配置文件。

無論如何,在 Spring 引導(當然是后端)中,我們通過WebSecurityConfigurerAdapter.configure(HttpSecurity http)方法以聲明方式啟用 CORS,如下所示:

@Override
protected void configure(HttpSecurity http) throws Exception {
  http.cors()...
}

cors() javadoc 指出:

添加要使用的 CorsFilter。 如果提供了名為 corsFilter 的 bean,則使用該 CorsFilter。 否則,如果定義了 corsConfigurationSource,則使用該 CorsConfiguration。

所以首先,檢查一下。

然后你有三個選擇:
– 不做任何額外的事情。 在這種情況下,Spring 安全將使用 Spring 安全提供的默認 class 和關聯的默認 CorsConfigurationSource bean。
– 聲明一個名為corsFilter的 bean。 在這種情況下,Spring 安全將使用它而不是默認值。
– 聲明一個名為corsConfigurationSource的 bean。 在這種情況下,Spring 將使用默認的 CorsFilter 和應用程序聲明的自定義corsConfigurationSource

你用的是最后一種方式。

如果這還不夠,您的WebSecurity配置中可能有一些東西會阻止在正確的時間處理 CORS 過濾器。
添加該屬性並花時間分析 Spring Security 對 CORS 所做的事情:

logging.level.org.springframework.security=DEBUG

幾個月前我寫了那篇文章 也許它可以幫助你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM