How to Fix the problem of No 'Access-Control-Allow-Origin' in a SpringBoot+Vuejs app build with Gradle plugin

huangapple go评论113阅读模式
英文:

How to Fix the problem of No 'Access-Control-Allow-Origin' in a SpringBoot+Vuejs app build with Gradle plugin

问题

在我本地使用嵌入式 H2 数据库工作时,问题没有出现;但一旦部署到 Heroku 并创建一个使用所有数据的 PostgreSQL 数据库后,问题就出现了。实际上,应用程序无法识别请求中带来的标头,导致以下响应:

  1. 跨源请求到'https://xxxxxx.herokuapp.com/bikes/all'从起源'http://localhost:8082'被阻止,因为 CORS 策略:请求的资源上没有'Access-Control-Allow-Origin'标头。如果不透明的响应满足您的需求,请将请求模式设置为'no-cors',以禁用带有 CORS 的资源。

Spring 使用的依赖项如下:

  1. dependencies {
  2. implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
  3. implementation 'org.springframework.boot:spring-boot-starter-data-rest'
  4. implementation 'org.springframework.boot:spring-boot-starter-security'
  5. implementation 'org.springframework.boot:spring-boot-starter-web'
  6. //runtimeOnly 'com.h2database:h2'
  7. compile("org.postgresql:postgresql")
  8. ......

在我的应用属性中,为了在部署到 Heroku 时连接到数据库,我进行了以下初始化:

  1. ### ----- 将此部分注释以在本地工作!从这里开始... -----
  2. spring.jackson.serialization.fail-on-empty-beans=false
  3. spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
  4. spring.datasource.driverClassName=org.postgresql.Driver
  5. spring.datasource.url=${JDBC_DATABASE_URL}
  6. spring.datasource.username=${JDBC_DATABASE_USERNAME}
  7. spring.datasource.password=${JDBC_DATABASE_PASSWORD}
  8. spring.datasource.testWhileIdle=true
  9. spring.datasource.validationQuery=SELECT 1
  10. spring.jpa.show-sql=true
  11. spring.jpa.generate-ddl=true
  12. spring.jpa.hibernate.ddl-auto=update

然后在我的应用程序类中,我启用了所有与 web 安全相关的内容,包括允许的来源,我将其声明为(*):

  1. @Configuration
  2. @EnableWebSecurity
  3. class WebSecurityConfiguration extends GlobalAuthenticationConfigurerAdapter {
  4. // ...
  5. }
  6. @Configuration
  7. @EnableWebSecurity
  8. class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  9. @Override
  10. protected void configure(HttpSecurity http) throws Exception {
  11. // ...
  12. }
  13. @Bean
  14. public CorsConfigurationSource corsConfigurationSource() {
  15. final CorsConfiguration configuration = new CorsConfiguration();
  16. // ...
  17. final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
  18. source.registerCorsConfiguration("/**", configuration);
  19. return source;
  20. }
  21. }

在前端中调用操作时,我尝试了三种不同的请求头设置,但问题仍然存在:

  1. const url = "xxxxxxxxx.herokuapp.com/";
  2. fetchAllBikesJson({ commit }) {
  3. fetch(url + "bikes/all", {
  4. credentials: "include",
  5. // Option 1
  6. headers: {
  7. "Access-Control-Allow-Origin": "*"
  8. },
  9. // Option 2
  10. headers: {
  11. "Access-Control-Allow-Origin": "http://localhost:8082"
  12. },
  13. // Option 3 (No headers)
  14. method: "GET",
  15. })
  16. .then((response) => {
  17. return response.json();
  18. })
  19. .then((response) => {
  20. // ...
  21. commit("setAllBikesJson", response);
  22. })
  23. .catch((error) => {
  24. // ...
  25. });
  26. },

你还提供了在网络控制台中捕获的错误视图截图,以及 Network 选项卡下的截图。

英文:

in this app im doing when i work in local with a h2-embeded database , the problem doesnt shows up, and only appears once i deploy to heroku and create a Postgresql database which use all the data from h2.
Literall y the app doesnt recognize the headers brought form the request , throwing as respopnse

  1. Access to fetch at 'https://xxxxxx.herokuapp.com/bikes/all' from origin 'http://localhost:8082'
  2. has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the
  3. requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors'
  4. to fetch the resource with CORS disabled.

The dependencies used for spring are:

  1. dependencies {
  2. implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
  3. implementation 'org.springframework.boot:spring-boot-starter-data-rest'
  4. implementation 'org.springframework.boot:spring-boot-starter-security'
  5. implementation 'org.springframework.boot:spring-boot-starter-web'
  6. //runtimeOnly 'com.h2database:h2'
  7. compile("org.postgresql:postgresql")
  8. ......

and in my app properties in order to connect with that database once is deployed to Heroku , i initialize this:

  1. ### ----- COMMENT THIS PART TO WORK IN LOCAL! FROM HERE... -----
  2. spring.jackson.serialization.fail-on-empty-beans=false
  3. spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
  4. spring.datasource.driverClassName=org.postgresql.Driver
  5. spring.datasource.url=${JDBC_DATABASE_URL}
  6. spring.datasource.username=${JDBC_DATABASE_USERNAME}
  7. spring.datasource.password=${JDBC_DATABASE_PASSWORD}
  8. spring.datasource.testWhileIdle=true
  9. spring.datasource.validationQuery=SELECT 1
  10. spring.jpa.show-sql=true
  11. spring.jpa.generate-ddl=true
  12. spring.jpa.hibernate.ddl-auto=update

Then on my application class , i do enable all referring to web security included the allowed origins which i declared as (*)

  1. @Configuration
  2. @EnableWebSecurity
  3. class WebSecurityConfiguration extends GlobalAuthenticationConfigurerAdapter {
  4. @Autowired
  5. UserRepository userRepository;
  6. @Override
  7. public void init(AuthenticationManagerBuilder auth) throws Exception {
  8. auth.userDetailsService(inputName-> {
  9. User user = userRepository.findByUserName(inputName);
  10. if (user != null) {
  11. return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getUserPassword(),
  12. AuthorityUtils.createAuthorityList("USER"));
  13. } else {
  14. throw new UsernameNotFoundException("Unknown user: " + inputName);
  15. }
  16. });
  17. }
  18. }
  19. @Configuration
  20. @EnableWebSecurity
  21. class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  22. @Override
  23. protected void configure(HttpSecurity http) throws Exception {
  24. http.cors();///de heroku tambien
  25. http.authorizeRequests()
  26. .antMatchers("/bikes/all").permitAll()
  27. .antMatchers("/bikes/user/register").permitAll()
  28. .antMatchers("/h2-console/**").permitAll()
  29. .antMatchers("/rest/**").hasAuthority("ADMIN")
  30. .antMatchers("/**").hasAuthority("USER")
  31. .anyRequest().fullyAuthenticated();
  32. http.formLogin()
  33. .usernameParameter("name")
  34. .passwordParameter("password")
  35. .loginPage("/bikes/login");
  36. http.logout().logoutUrl("/api/logout");
  37. http.csrf().disable();
  38. http.exceptionHandling().authenticationEntryPoint((req, res, exc) -> res.sendError(HttpServletResponse.SC_UNAUTHORIZED));
  39. http.formLogin().successHandler((req, res, auth) -> clearAuthenticationAttributes(req));
  40. http.formLogin().failureHandler((req, res, exc) -> res.sendError(HttpServletResponse.SC_UNAUTHORIZED));
  41. http.logout().logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler());
  42. http.headers().frameOptions().sameOrigin();
  43. }
  44. private void clearAuthenticationAttributes(HttpServletRequest request) {
  45. HttpSession session = request.getSession(false);
  46. if (session != null) {
  47. session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
  48. }
  49. }
  50. @Bean
  51. public CorsConfigurationSource corsConfigurationSource() {
  52. final CorsConfiguration configuration = new CorsConfiguration();
  53. configuration.setAllowedOrigins(Arrays.asList("*"));
  54. configuration.setAllowedMethods(Arrays.asList("HEAD",
  55. "GET", "POST", "PUT", "DELETE", "PATCH"));
  56. configuration.setAllowCredentials(true);
  57. configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
  58. final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
  59. source.registerCorsConfiguration("/**", configuration);
  60. return source;
  61. }

Even as alternative isntead of (*), i specified the exact origin might be allowed , iin this case

  1. http://localhost:8082(cause im doing the request of my front from local)

But neither works

In my front end calling the action , either put the header specifying the origing allowed (*), or localhot :8082, or even none , and still the error persists

  1. const url=xxxxxxxxx.herokuapp.com/
  2. fetchAllBikesJson({ commit}) {
  3. fetch(url +"bikes/all", {
  4. credentials: "include",
  5. Option1
  6. headers: {
  7. "Access-Control-Allow-Origin": "*"
  8. },
  9. Option 2
  10. headers: {
  11. "Access-Control-Allow-Origin": "http://localhost:8082"
  12. },
  13. Option 2
  14. NO HEADERS
  15. method: "GET",
  16. })
  17. .then((response) => {
  18. return response.json();
  19. })
  20. .then((response) => {
  21. // console.log(response);
  22. response;
  23. commit("setAllBikesJson", response);
  24. })
  25. .catch((error) => {
  26. // console.log("error", error);
  27. error;
  28. });
  29. },

Also adding a view for the error from my wen console as well as one from my web console in the Network item

How to Fix the problem of No 'Access-Control-Allow-Origin' in a SpringBoot+Vuejs app build with Gradle plugin

How to Fix the problem of No 'Access-Control-Allow-Origin' in a SpringBoot+Vuejs app build with Gradle plugin
Any help about about his issue .thanks in advance!!!!

答案1

得分: 2

尝试定义配置而不是bean跨域配置。

  1. @Configuration
  2. public class CorsConfiguration implements WebMvcConfigurer {
  3. @Override
  4. public void addCorsMappings(CorsRegistry registry) {
  5. registry.addMapping("/**")
  6. .allowedOrigins("*")
  7. .allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS");
  8. }
  9. }

另外,我注意到你的代码中有这样的部分:

  1. http.cors();
  2. ....
  3. ...http.etc()
  4. 而应该是 http.cors().and() // 可能这是你的问题

请参考这个链接

英文:

Try defining the configuration instead of bean cors configuration

  1. @Configuration
  2. public class CorsConfiguration implements WebMvcConfigurer {
  3. @Override
  4. public void addCorsMappings(CorsRegistry registry) {
  5. registry.addMapping("/**")
  6. .allowedOrigins("*")
  7. .allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS");
  8. }
  9. }

Also I noticed that you have in your code like this:

  1. http.cors();
  2. ....
  3. ...http.etc()
  4. Instead it should be http.cors().and() // May be this is your issue

Please check this

huangapple
  • 本文由 发表于 2020年9月16日 23:06:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/63922943.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定