英文:
How to Fix the problem of No 'Access-Control-Allow-Origin' in a SpringBoot+Vuejs app build with Gradle plugin
问题
在我本地使用嵌入式 H2 数据库工作时,问题没有出现;但一旦部署到 Heroku 并创建一个使用所有数据的 PostgreSQL 数据库后,问题就出现了。实际上,应用程序无法识别请求中带来的标头,导致以下响应:
跨源请求到'https://xxxxxx.herokuapp.com/bikes/all'从起源'http://localhost:8082'被阻止,因为 CORS 策略:请求的资源上没有'Access-Control-Allow-Origin'标头。如果不透明的响应满足您的需求,请将请求模式设置为'no-cors',以禁用带有 CORS 的资源。
Spring 使用的依赖项如下:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-rest'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
//runtimeOnly 'com.h2database:h2'
compile("org.postgresql:postgresql")
......
在我的应用属性中,为了在部署到 Heroku 时连接到数据库,我进行了以下初始化:
### ----- 将此部分注释以在本地工作!从这里开始... -----
spring.jackson.serialization.fail-on-empty-beans=false
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=${JDBC_DATABASE_URL}
spring.datasource.username=${JDBC_DATABASE_USERNAME}
spring.datasource.password=${JDBC_DATABASE_PASSWORD}
spring.datasource.testWhileIdle=true
spring.datasource.validationQuery=SELECT 1
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
然后在我的应用程序类中,我启用了所有与 web 安全相关的内容,包括允许的来源,我将其声明为(*):
@Configuration
@EnableWebSecurity
class WebSecurityConfiguration extends GlobalAuthenticationConfigurerAdapter {
// ...
}
@Configuration
@EnableWebSecurity
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// ...
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
// ...
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
在前端中调用操作时,我尝试了三种不同的请求头设置,但问题仍然存在:
const url = "xxxxxxxxx.herokuapp.com/";
fetchAllBikesJson({ commit }) {
fetch(url + "bikes/all", {
credentials: "include",
// Option 1
headers: {
"Access-Control-Allow-Origin": "*"
},
// Option 2
headers: {
"Access-Control-Allow-Origin": "http://localhost:8082"
},
// Option 3 (No headers)
method: "GET",
})
.then((response) => {
return response.json();
})
.then((response) => {
// ...
commit("setAllBikesJson", response);
})
.catch((error) => {
// ...
});
},
你还提供了在网络控制台中捕获的错误视图截图,以及 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
Access to fetch at 'https://xxxxxx.herokuapp.com/bikes/all' from origin 'http://localhost:8082'
has been blocked by CORS policy: 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.
The dependencies used for spring are:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-rest'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
//runtimeOnly 'com.h2database:h2'
compile("org.postgresql:postgresql")
......
and in my app properties in order to connect with that database once is deployed to Heroku , i initialize this:
### ----- COMMENT THIS PART TO WORK IN LOCAL! FROM HERE... -----
spring.jackson.serialization.fail-on-empty-beans=false
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=${JDBC_DATABASE_URL}
spring.datasource.username=${JDBC_DATABASE_USERNAME}
spring.datasource.password=${JDBC_DATABASE_PASSWORD}
spring.datasource.testWhileIdle=true
spring.datasource.validationQuery=SELECT 1
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
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 (*)
@Configuration
@EnableWebSecurity
class WebSecurityConfiguration extends GlobalAuthenticationConfigurerAdapter {
@Autowired
UserRepository userRepository;
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(inputName-> {
User user = userRepository.findByUserName(inputName);
if (user != null) {
return new org.springframework.security.core.userdetails.User(user.getUserName(), user.getUserPassword(),
AuthorityUtils.createAuthorityList("USER"));
} else {
throw new UsernameNotFoundException("Unknown user: " + inputName);
}
});
}
}
@Configuration
@EnableWebSecurity
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors();///de heroku tambien
http.authorizeRequests()
.antMatchers("/bikes/all").permitAll()
.antMatchers("/bikes/user/register").permitAll()
.antMatchers("/h2-console/**").permitAll()
.antMatchers("/rest/**").hasAuthority("ADMIN")
.antMatchers("/**").hasAuthority("USER")
.anyRequest().fullyAuthenticated();
http.formLogin()
.usernameParameter("name")
.passwordParameter("password")
.loginPage("/bikes/login");
http.logout().logoutUrl("/api/logout");
http.csrf().disable();
http.exceptionHandling().authenticationEntryPoint((req, res, exc) -> res.sendError(HttpServletResponse.SC_UNAUTHORIZED));
http.formLogin().successHandler((req, res, auth) -> clearAuthenticationAttributes(req));
http.formLogin().failureHandler((req, res, exc) -> res.sendError(HttpServletResponse.SC_UNAUTHORIZED));
http.logout().logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler());
http.headers().frameOptions().sameOrigin();
}
private void clearAuthenticationAttributes(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null) {
session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
}
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("HEAD",
"GET", "POST", "PUT", "DELETE", "PATCH"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
Even as alternative isntead of (*), i specified the exact origin might be allowed , iin this case
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
const url=xxxxxxxxx.herokuapp.com/
fetchAllBikesJson({ commit}) {
fetch(url +"bikes/all", {
credentials: "include",
Option1
headers: {
"Access-Control-Allow-Origin": "*"
},
Option 2
headers: {
"Access-Control-Allow-Origin": "http://localhost:8082"
},
Option 2
NO HEADERS
method: "GET",
})
.then((response) => {
return response.json();
})
.then((response) => {
// console.log(response);
response;
commit("setAllBikesJson", response);
})
.catch((error) => {
// console.log("error", error);
error;
});
},
Also adding a view for the error from my wen console as well as one from my web console in the Network item
答案1
得分: 2
尝试定义配置而不是bean跨域配置。
@Configuration
public class CorsConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS");
}
}
另外,我注意到你的代码中有这样的部分:
http.cors();
....
...http.etc()
而应该是 http.cors().and() // 可能这是你的问题
请参考这个链接。
英文:
Try defining the configuration instead of bean cors configuration
@Configuration
public class CorsConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS");
}
}
Also I noticed that you have in your code like this:
http.cors();
....
...http.etc()
Instead it should be http.cors().and() // May be this is your issue
Please check this
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论