[英]Unable To Make Spring Boot API Request Due To CORS Docker
I have a React frontend app that makes an API call to a Spring boot app.我有一个 React 前端应用程序,它对 Spring 启动应用程序进行 API 调用。
Both are in separate docker containers.两者都在单独的 docker 容器中。 When it's run locally everything is fine, however after deployment, when the call is made, I get a CORS error:
当它在本地运行时,一切都很好,但是在部署之后,当调用时,我得到一个 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.
I'm not sure why this is the case.我不确定为什么会这样。 To my mind I've coded up everything to allow CORS access (as I said it works locally, so I don't understand why it fails after deployment. I've read up a bit about docker and localhost but it just seems quite confusing to me at the moment.
在我看来,我已经编写了所有代码以允许 CORS 访问(正如我所说它在本地工作,所以我不明白为什么它在部署后失败。我已经阅读了一些关于 docker 和 localhost 的信息,但它看起来很混乱对我来说。
This is my Java Security code from WebSecurityConfigurerAdapter
:这是我来自
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
is as follows: 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
And finally the nginx.conf
:最后是
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;
}
}
}
What do I need to do with the containers to allow CORS access?我需要对容器做什么才能允许 CORS 访问?
First: to benefit from CORS, you don't need to focus on http client configuration.第一:要从 CORS 中受益,您无需关注 http 客户端配置。
The authorization is allowed only by the backend that answers to the question: is that host, port, request acceptable?只有回答以下问题的后端才允许授权:该主机、端口、请求是否可接受? Contrary to CSRF that requires configuration both client and server.
与需要配置客户端和服务器的 CSRF 相反。
I mention that since you expose your client conf.我提到这一点,因为您公开了您的客户配置文件。
In any way, in Spring Boot (backend of course), we enable CORS declaratively from the WebSecurityConfigurerAdapter.configure(HttpSecurity http)
method as simply as:无论如何,在 Spring 引导(当然是后端)中,我们通过
WebSecurityConfigurerAdapter.configure(HttpSecurity http)
方法以声明方式启用 CORS,如下所示:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors()...
}
The cors()
javadoc states that: cors()
javadoc 指出:
Adds a CorsFilter to be used.
添加要使用的 CorsFilter。 If a bean by the name of corsFilter is provided, that CorsFilter is used.
如果提供了名为 corsFilter 的 bean,则使用该 CorsFilter。 Else if corsConfigurationSource is defined, then that CorsConfiguration is used.
否则,如果定义了 corsConfigurationSource,则使用该 CorsConfiguration。
So first, check that.所以首先,检查一下。
Then you have three options:然后你有三个选择:
– to do no additional thing. – 不做任何额外的事情。 In this case, Spring security will use the default class provided by Spring security and the default CorsConfigurationSource bean associated to.
在这种情况下,Spring 安全将使用 Spring 安全提供的默认 class 和关联的默认 CorsConfigurationSource bean。
– to declare a bean named corsFilter
. – 声明一个名为
corsFilter
的 bean。 In this case, Spring security will use it instead of the default.在这种情况下,Spring 安全将使用它而不是默认值。
– to declare a bean named corsConfigurationSource
. – 声明一个名为
corsConfigurationSource
的 bean。 In that case, Spring will use the default CorsFilter with the custom corsConfigurationSource
declared by the application.在这种情况下,Spring 将使用默认的 CorsFilter 和应用程序声明的自定义
corsConfigurationSource
。
You used the last way.你用的是最后一种方式。
If it is not enough, you may have something in your WebSecurity
configs that prevents the CORS filter to be handled at the right time.如果这还不够,您的
WebSecurity
配置中可能有一些东西会阻止在正确的时间处理 CORS 过滤器。
Add that property and take time to analyse what Spring Security does about CORS:添加该属性并花时间分析 Spring Security 对 CORS 所做的事情:
logging.level.org.springframework.security=DEBUG
I wrote that post some months ago.几个月前我写了那篇文章。 Maybe it could help you.
也许它可以帮助你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.