这是我第一次使用 springboot,我遇到了 cors 配置的问题。 我尝试了很多事情,但我似乎总是得到: 从源“http://localhost:3000”获取“http://localhost:52700/greeting-javaconfig”的访问已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:它没有HTTP 状态正常。
这个错误我已经有一周左右的时间了,我已经使用了具有许多属性的 cors 配置文件,但我似乎无法使其工作
我使用以下代码在我的配置文件夹中创建了一个 CorsConfig.java 文件:
package com.example.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*") // Allow requests from any origin
.allowedMethods("GET", "POST", "PUT", "DELETE") // Allowed HTTP methods
.allowedHeaders("*"); // Allowed headers
}
@Bean
CorsWebFilter corsWebFilter() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
}
它对我来说看起来很标准,我看到很多例子都使用这种或多或少相同的格式
而且我还注意到我需要一些示例中的 cors 过滤器,因此我在注意到没有它仍然无法工作后也将其添加到项目中:
package com.example.config;
import org.springframework.stereotype.Component;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
@Component
public class CorsFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
exchange.getResponse().getHeaders().add("Access-Control-Allow-Origin", "*");
exchange.getResponse().getHeaders().add("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS");
exchange.getResponse().getHeaders().add("Access-Control-Allow-Headers", "Content-Type, Authorization");
exchange.getResponse().getHeaders().add("Access-Control-Max-Age", "3600");
return chain.filter(exchange);
}
}
当使用调试器和邮递员测试此代码时,我得到响应,并且断点将抛出此过滤器函数。
我也有基本的身份验证,我不知道这对问题是否重要,但无论如何我都会使用控制器添加我的代码,以防万一我没有遗漏任何重要信息。
SecurityConfig.java:
package com.example.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.server.SecurityWebFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring()
// Spring Security should completely ignore URLs starting with /resources/
.requestMatchers("/**");
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests().requestMatchers("/**").permitAll().anyRequest()
.hasRole("USER").and()
.formLogin()
.permitAll();
http.cors().disable();
return http.build();
}
@Bean
public MapReactiveUserDetailsService userDetailsService() {
UserDetails user = User
.withUsername("user1")
.password("{noop}user1Pass") // {noop} for plain text, consider a password encoder for production
.roles("USER")
.build();
return new MapReactiveUserDetailsService(user);
}
}
基础控制器:
package com.example.controller;
import com.makalu.makaluapi.models.Greeting;
import org.springframework.web.bind.annotation.*;
import java.util.concurrent.atomic.AtomicLong;
@RestController
public class BaseController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
@CrossOrigin(origins = "http://localhost:3000/")
@GetMapping("/greeting-javaconfig")
public Greeting greeting(@RequestParam(required = false, defaultValue = "World") String name) {
System.out.println("==== get greeting ====");
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
}
尝试让它发挥作用确实令人沮丧,但这仍然是一个有趣且重要的话题。我将不胜感激有关此主题的任何信息,谢谢!
这也是我用于 api 调用的代码,我尝试过:
const url = 'http://localhost:52700/greeting-javaconfig';
username = 'user1';
password = 'user1Pass';
const credentials = btoa(username + ':' + password);
const options = {
method: 'GET',
headers: {
'Authorization': 'Basic ' + credentials,
'Content-Type': 'application/json',
'Accept': 'text/html',
'cache-control': 'no-cache'
},
// credentials: 'same-origin'
};
// @ts-ignore
fetch(url, options).then(response => {
console.log(response.body);
})
有关更多上下文,我还可以运行此curl请求:
curl -v -u user1:user1Pass -H "Access-Control-Request-Method: GET" -H "Origin: http://localhost:3004" -X GET http://localhost:52700/greeting-javaconfig
并得到这个输出:
Note: Unnecessary use of -X or --request, GET is already inferred.
* Trying 127.0.0.1:52700...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 52700 (#0)
* Server auth using Basic with user 'user1'
> GET /greeting-javaconfig HTTP/1.1
> Host: localhost:52700
> Authorization: Basic dXNlcjE6dXNlcjFQYXNz
> User-Agent: curl/7.68.0
> Accept: */*
> Access-Control-Request-Method: GET
> Origin: http://localhost:3004
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS
< Access-Control-Allow-Headers: Content-Type, Authorization
< Access-Control-Max-Age: 3600
< Vary: Origin
< Vary: Access-Control-Request-Method
< Vary: Access-Control-Request-Headers
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Content-Type-Options: nosniff
< X-Frame-Options: DENY
< X-XSS-Protection: 0
< Referrer-Policy: no-referrer
< Content-Type: application/json
< Content-Length: 34
< Date: Tue, 16 Apr 2024 08:43:30 GMT
<
我不知道它是否重要,但无论如何我都会添加它以获取更多上下文。
我原本期望得到 200OK,但在客户端中未经授权得到 401,但在邮递员中我得到 200OK 和返回值。
几天前我遇到了类似的问题,浏览器工具控制台向我显示了 Cors CrossOrigin 的错误,我开始查看与此相关的所有内容。几天后我意识到问题不在 CORS 上,问题是防火墙阻止了端口 8085 的访问,因此控制台显示 CORS 错误。
检查您是否正在访问正确的端口,并且没有防火墙阻止访问,在这里您可以找到类似的错误,CORS有时可能非常通用。无论如何我希望它对你有帮助!
将凭据与
Access-Control-Allow-Origin: *
结合使用会导致问题,请参阅 https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
请在 CORS 配置中指定您的已知来源,即
http://localhost:3000
而不是星号。