По некоторым причинам эта простая проблема блокирует многих разработчиков. Я боролся в течение многих часов с этой простой вещью. Эта проблема как много размеров:
CORS
Моя установка для разработки является с vuejs webpack приложением, работающим localhost:8081 и пружинным приложением начальной загрузки, работающим localhost:8080. Таким образом, при попытке назвать отдых API от frontend, нет никакого способа, которым браузер позволит мне получить ответ от пружинного бэкенда без надлежащих настроек CORS. CORS может использоваться для ослабления Перекрестного Доменного Сценария (XSS) защита, которую имеют современные браузеры. Поскольку я понимаю это, браузеры защищают Ваш SPA от того, чтобы быть нападением XSS. Конечно, некоторые ответы на 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 в Вашем контроллере.
Frontend
Теперь, в frontend необходимо создать запрос 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>
Hope это помогает.
Решение, данное luschn и pillravi, хорошо работает, если Вы не получаете Строгая Транспортная безопасность заголовок в ответе.
Добавление withCredentials: верный решит ту проблему.
axios.post(session_url, {
withCredentials: true,
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
}
},{
auth: {
username: "USERNAME",
password: "PASSWORD"
}}).then(function(response) {
console.log('Authenticated');
}).catch(function(error) {
console.log('Error on Authentication');
});