З деяких причин ця проста проблема блокує багатьох розробників. Я багато годин боровся з цією простою справою. У цій проблемі стільки вимірів:
- CORS (якщо ви використовуєте інтерфейс і бекенд на різних доменах та портах.
- Конфігурація вихідного CORS
- Базова конфігурація автентифікації Axios
CORS
Моє налаштування для розробки - це програма vuejs webpack, запущена на localhost: 8081, та програма для весняного завантаження, що працює на localhost: 8080. Отже, намагаючись викликати rest інтерфейс з інтерфейсу, браузер не має можливості дозволити мені отримати відповідь від весняної серверної системи без належних налаштувань CORS. CORS може бути використаний для розслаблення захисту міждоменного сценарію (XSS), який має сучасний браузер. Як я розумію, браузери захищають ваш SPA від атаки XSS. Звичайно, деякі відповіді на StackOverflow пропонували додати chrome-плагін, щоб вимкнути захист 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.
Фронтенд
Тепер у фронтенді вам потрібно створити запит axios за допомогою заголовка Authorization:
<!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>
Сподіваюся, це допомагає.