Spring Boot 使用Angular在Sping Boot 中启用了Cors,但仍然存在错误

0ve6wy6x  于 2023-10-16  发布在  Spring
关注(0)|答案(8)|浏览(160)

我已经为所有的origins和header启用了cors,但是当我从angular应用程序调用get方法到spring Boot 时,我仍然会得到一个cors错误。
来自控制台的Cors错误:

Access to XMLHttpRequest at 'http://localhost:8080/api/users/[email protected]' 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);
    }

}

在这里我调用get from my angular app:

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

但还是没找到...

nwlqm0z1

nwlqm0z11#

这可能是由于Spring库的更改,从而影响Sping 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的功能。它允许您定义更灵活的模式,而后者实际上是在EST-Control-Allow-Origin头中返回的值,并且不允许将“*”与allowCredentials=true组合使用。这一变化在WebMvc和WebFlux配置中引入了等效的allowedOriginPatterns方法,但在SockJS配置和AbstractSocketJsService中没有。

我会在5.3.2中添加这些内容。然后,您需要切换到allowedOriginPatterns而不是allowedOrigins,但这为您提供了一个选项来更精确地定义允许的域模式。同时,如果可行的话,你可以通过列出特定的域来解决这个问题。

isr3a4wc

isr3a4wc2#

这个问题背后的原因已经在answer中清楚地提到了,简单地说,CorsRegistry#allowCredentials(true)不能与默认值CorsRegistry#allowedOrigins()一起使用(默认情况下,如果您没有设置此属性,则允许所有原点,除非设置了CorsRegistry#allowedOriginPatterns()

  • 用最典型的Sping Boot corsMappings来解释这个问题:
@Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedMethods("*")
                        .allowCredentials(true);
            }
        };
    }

在上面的例子中,allowCredentials被设置为true,同时allowedOrigins没有被配置,这意味着默认情况下允许所有原点(allowedOrigins的值将是*****)。

  • 要解决此问题,必须显式设置allowedOriginsallowedOriginPatterns。在下面的代码片段中,使用了allowedOriginPatterns,并将值设置为-> "https://*.domain.com"。此URL模式匹配来自domain.com的任何主机和URL模式,如https:microservice.division.domain.com
@Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedMethods("*")
                        .allowedOriginPatterns("https://*.domain.com");
            }
        };
    }

完整的代码片段link

v2g6jxz6

v2g6jxz63#

corsConfiguration.setAllowedOrigins("*")更改为corsConfiguration.setAllowedOriginPatterns("*")对我来说很有用!
所以基本上是setAllowedOriginssetAllowedOriginPatterns

brjng4g3

brjng4g34#

在您的控制器上尝试以下操作

@CrossOrigin(origins = "*", allowCredentials = "true", allowedHeaders = "*", exposedHeaders = "If-Match")
9jyewag0

9jyewag05#

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);
    }

这也修复了controller@CrossOrigin(origins = "*", allowedHeaders = "*")的cors错误。

ewm0tg9j

ewm0tg9j6#

我得到错误时的场景是:
我已经在我的Sping Boot Server应用程序中添加了Sping Boot Security Dependent。
与您的跟踪类似,我添加了CrossOrigin()注解来解决这个问题。但这个问题并没有得到解决。
我通过在请求的头选项中添加基本身份验证来解决这个问题。
请参考帖子,了解如何在头中添加基本身份验证:
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')
})
};

请输入您的用户名和密码登录默认情况下,Sping Boot 中的用户名是“user”,密码将在启动Sping 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();
    }
}

参考文献:

希望解决方案对你有帮助。
谢谢你,

4ktjp1zp

4ktjp1zp7#

您应该创建一个名为“"的类,代码如下

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、REPORT和OPTIONS。

vlju58qv

vlju58qv8#

最近我遇到了同样的问题,尝试了所有可能的方法,但都没有成功。我使用的是spring 2.6.7,我添加了下面的代码来解决这个问题。
在Sping Boot main类中可以添加以下代码

@Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedOrigins("*").allowedMethods("*");
            }
        };
    }

你可以看到我添加了addMapping("/**").allowedOrigins("*").allowedMethods("*");
快乐编码!!

相关问题