在带有 Angular 的 Spring Boot 中启用了 Cors,但仍然出现 cors 错误
Posted
技术标签:
【中文标题】在带有 Angular 的 Spring Boot 中启用了 Cors,但仍然出现 cors 错误【英文标题】:Cors enabled in Spring Boot with Angular, still cors errors 【发布时间】:2021-03-01 16:37:07 【问题描述】:我为所有来源和标头启用了 cors,但是当我从我的 angular 应用程序调用 get
方法到 spring boot 时,我仍然收到 cors 错误。
来自控制台的 Cors 错误:
Access to XMLHttpRequest at 'http://localhost:8080/api/users/test@ronny.nl' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
我的controller
(我叫getbyemail):
@CrossOrigin(origins = "*", allowedHeaders = "*")
@RestController
@RequestMapping(value = "/api/users", produces = MediaType.APPLICATION_JSON_VALUE)
public class UserController
private final UserService userService;
@Autowired
public UserController(final UserService userService)
this.userService = userService;
@GetMapping
public List<UserDTO> getAllUsers()
return userService.findAll();
@GetMapping("/id")
public UserDTO getUser(@PathVariable final Long id)
return userService.get(id);
@CrossOrigin(origins = "*", allowedHeaders = "*")
@GetMapping("/email")
public UserDTO getUserByMail(@PathVariable String email)
return userService.getByEmail(email);
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Long createUser(@RequestBody @Valid final UserDTO userDTO)
return userService.create(userDTO);
@PutMapping("/id")
public void updateUser(@PathVariable final Long id, @RequestBody @Valid final UserDTO userDTO)
userService.update(id, userDTO);
@DeleteMapping("/id")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteUser(@PathVariable final Long id)
userService.delete(id);
我从我的 Angular 应用中调用 get 的地方:
onSubmit(): void
this.submitted = true;
this.wrongInput = false;
this.loginService.getLogin<User>(this.loginForm.value.email).subscribe((response) =>
this.tempUser = response;
console.log(this.tempUser);
if (this.loginForm.value.email === this.tempUser.email && this.loginForm.value.password === this.tempUser.password)
this.localStorageService.save(this.tempUser);
this.router.navigate(['/home']);
console.log(true);
else
this.wrongInput = true;
);
我也尝试添加DevCorsConfiguration
:
package com.team13.triviaquiz.triviaquizserver.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@Profile("development")
public class DevCorsConfiguration implements WebMvcConfigurer
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/api/**").allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS");
并在我的application.properties
中添加了个人资料:
application.properties
spring.profiles.active=development
#enabling h2 console
spring.h2.console.enabled=true
#fixed URL for H2 (necessary from Spring 2.3.0)
spring.datasource.url=jdbc:h2:mem:triviaquizserver
#turn statistics on
spring.jpa.properties.hibernate.generate_statistics = true
logging.level.org.hibernate.stat=debug
#show all queries
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.type=trace
但还是没有运气......
【问题讨论】:
【参考方案1】:在您的控制器上尝试以下操作
@CrossOrigin(origins = "*", allowCredentials = "true", allowedHeaders = "*", exposedHeaders = "If-Match")
【讨论】:
然后我得到另一个错误:当 allowCredentials 为真时,allowedOrigins 不能包含特殊值“*”,因为它不能在“Access-Control-Allow-Origin”响应标头上设置。要允许一组来源的凭据,请明确列出它们或考虑改用“allowedOriginPatterns”。 我能够通过在 WebSecurityConfig 上使用 addAllowedOriginPattern(*) 来解决此问题。【参考方案2】:cors 错误来自为我的两个 get 方法处理不明确的处理程序错误。
我的controller
中有两个get 方法,一个是integer
,另一个是String
。所以它无法真正弄清楚解析字符串或 int(我认为)我已将 get 方法的 bot 路径更改为:
@GetMapping("/id/id")
public UserDTO getUser(@PathVariable final Long id)
return userService.get(id);
@GetMapping("/email/email")
public UserDTO getUserByMail(@PathVariable String email)
return userService.getByEmail(email);
这也修复了 @CrossOrigin(origins = "*", allowedHeaders = "*")
的 cors 错误
在controller
。
【讨论】:
【参考方案3】:这可能是由于 Spring 库的更改,从而影响了 Spring Boot 2.4.0。 看这里https://github.com/spring-projects/spring-framework/issues/26111 及其相关票证https://github.com/spring-projects/spring-framework/pull/26108
编辑 这是来自第一个链接的原始消息:
#25016 引入了除了 allowedOrigins 之外还可以配置 allowedOriginPatterns 的功能。它让您定义更灵活 模式,而后者实际上是返回的值 Access-Control-Allow-Origin 标头,并且不允许使用“*” 与 allowCredentials=true 组合。引入的变化 WebMvc 和 WebFlux 中的等效 allowedOriginPatterns 方法 config,但不在 SockJS 配置和 AbstractSocketJsService 中。
我将为 5.3.2 添加这些内容。然后你需要切换到 allowedOriginPatterns 而不是 allowedOrigins 但这会给你一个 更精确地定义允许的域模式的选项。在里面 同时,您可以通过列出特定的 域,如果可行的话。
【讨论】:
虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review 有道理,编辑了答案。谢谢提示【参考方案4】:这个问题背后的原因在answer中已经明确提到了,简单地说CorsRegistry#allowCredentials(true)
不能与默认值CorsRegistry#allowedOrigins()
一起使用(默认情况下,如果您没有设置此属性,则允许所有来源,除非任何CorsRegistry#allowedOriginPatterns()
已设置)
@Bean
public WebMvcConfigurer corsConfigurer()
return new WebMvcConfigurer()
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**").allowedMethods("*").allowCredentials(true);
;
在上面的例子中allowCredentials
被设置为true
,同时allowedOrigins
没有被配置,这意味着默认情况下所有的来源都是允许的(allowedOrigins
的值将是*
)。
allowedOrigins
或allowedOriginPatterns
。
在下面的代码 sn-p 中,使用了 allowedOriginPatterns
,并将值设置为 -> "https://*.domain.com"
。此通配符模式匹配来自 domain.com 的任何主机和诸如 https:microservice.division.domain.com 之类的 url 模式
@Bean
public WebMvcConfigurer corsConfigurer()
return new WebMvcConfigurer()
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**").allowedMethods("*").allowedOriginPatterns("https://*.domain.com");
;
完整代码sn -p link
【讨论】:
【参考方案5】:我收到错误时的情景是:
我已经在我的 Spring Boot 服务器应用程序中添加了 Spring Boot 安全依赖项。
与您的跟踪类似,我添加了 CrossOrigin() 注释来解决问题。但问题并没有得到解决。
我通过在请求的标头选项中添加基本身份验证解决了这个问题。
在header中添加基本认证请参考帖子:
Angular 6 HTTP Get request with HTTP-Basic authentication
import HttpHeaders from '@angular/common/http';
const httpOptions =
headers: new HttpHeaders(
'Content-Type': 'application/json',
'Authorization': 'Basic ' + btoa('username:password')
)
;
用您的用户名和密码替换用户名和密码。 默认情况下,Spring boot 中的用户名是“user”,密码将在启动 Spring Boot 应用程序的控制台上生成。
注意:您还必须将 CrossOrigin Annotation 添加到您的 RequestMapping 中。
由于您使用的是基本身份验证,您应该添加 WebSecurityConfiguration 以允许安全配置如下:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Override
protected void configure(HttpSecurity http) throws Exception
http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
http.cors();
参考资料:
https://www.baeldung.com/spring-security-cors-preflight https://www.baeldung.com/spring-security-basic-authentication希望解决方案对您有所帮助。
谢谢 昌都
【讨论】:
【参考方案6】:更改corsConfiguration.setAllowedOrigins("*")
corsConfiguration.setAllowedOriginPatterns("*")
为我成功了!
所以基本上是setAllowedOrigins
到setAllowedOriginPatterns
【讨论】:
【参考方案7】:你应该创建一个名为“”的类,代码如下
package com.api.juego.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer
private final long MAX_AGE_SECS = 3600;
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(false)
.maxAge(MAX_AGE_SECS);
出于安全原因,允许的方法是 GET、POST、PUT、PATCH、DELETE 和 OPTIONS。
【讨论】:
以上是关于在带有 Angular 的 Spring Boot 中启用了 Cors,但仍然出现 cors 错误的主要内容,如果未能解决你的问题,请参考以下文章
带有spring boot LDAP身份验证的Angular2
带有 Spring Boot 和 Spring Security 的 Angular2
带有 Keycloak 的 Angular/Spring Boot 抛出 403
在 Angular5 和 Spring Boot 中上传带有 JSON 数据的文件