어떤 이유로이 간단한 문제로 인해 많은 개발자가 차단됩니다. 나는이 간단한 일로 여러 시간 동안 고생했다. 이 문제는 여러 차원으로 :
- CORS (다른 도메인 및 포트에서 프런트 엔드 및 백엔드를 사용하는 경우.
- 백엔드 CORS 구성
- Axios의 기본 인증 구성
CORS
개발을위한 설정은 localhost : 8081에서 실행되는 vuejs 웹팩 애플리케이션과 localhost : 8080에서 실행되는 스프링 부트 애플리케이션입니다. 따라서 프론트 엔드에서 나머지 API를 호출하려고 할 때 브라우저가 적절한 CORS 설정없이 스프링 백엔드에서 응답을받을 수있는 방법이 없습니다. CORS를 사용하여 최신 브라우저에있는 XSS (Cross Domain Script) 보호를 완화 할 수 있습니다. 내가 알고 있듯이 브라우저는 XSS의 공격으로부터 SPA를 보호하고 있습니다. 물론 StackOverflow에 대한 일부 답변은 XSS 보호를 비활성화하기 위해 크롬 플러그인을 추가하도록 제안했지만 실제로 작동하며 만약 그렇다면 나중에 불가피한 문제를 밀어 붙일 것입니다.
백엔드 CORS 구성
스프링 부트 앱에서 CORS를 설정하는 방법은 다음과 같습니다.
CorsFilter 클래스를 추가하여 클라이언트 요청에 대한 응답에 적절한 헤더를 추가합니다. Access-Control-Allow-Origin 및 Access-Control-Allow-Headers는 기본 인증에있어 가장 중요한 것입니다.
public class CorsFilter implements Filter {
...
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest) servletRequest;
response.setHeader("Access-Control-Allow-Origin", "http://localhost:8081");
response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH");
**response.setHeader("Access-Control-Allow-Headers", "authorization, Content-Type");**
response.setHeader("Access-Control-Max-Age", "3600");
filterChain.doFilter(servletRequest, servletResponse);
}
...
}
Spring WebSecurityConfigurationAdapter를 확장하는 구성 클래스를 추가하십시오. 이 클래스에서는 CORS 필터를 삽입합니다.
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
@Bean
CorsFilter corsFilter() {
CorsFilter filter = new CorsFilter();
return filter;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(corsFilter(), SessionManagementFilter.class) //adds your custom CorsFilter
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/api/login")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.authenticationProvider(getProvider());
}
...
}
컨트롤러에 CORS와 관련된 어떤 것도 넣을 필요가 없습니다.
프런트 엔드
이제 프런트 엔드에서 Authorization 헤더를 사용하여 axios 쿼리를 만들어야합니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<p>{{ status }}</p>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
status: ''
},
created: function () {
this.getBackendResource();
},
methods: {
getBackendResource: function () {
this.status = 'Loading...';
var vm = this;
var user = "aUserName";
var pass = "aPassword";
var url = 'http://localhost:8080/api/resource';
var authorizationBasic = window.btoa(user + ':' + pass);
var config = {
"headers": {
"Authorization": "Basic " + authorizationBasic
}
};
axios.get(url, config)
.then(function (response) {
vm.status = response.data[0];
})
.catch(function (error) {
vm.status = 'An error occured.' + error;
})
}
}
})
</script>
</body>
</html>
도움이 되었기를 바랍니다.