Pour certaines raisons, ce problème simple bloque de nombreux développeurs. J'ai lutté pendant de nombreuses heures avec cette simple chose. Ce problème a plusieurs dimensions :
- CORS (si vous utilisez un frontend et un backend sur différents domaines et ports.
- Configuration CORS du backend
- Configuration de l'authentification de base d'Axios
CORS
Ma configuration pour le développement est avec une application vuejs webpack fonctionnant sur localhost:8081 et une application spring boot fonctionnant sur localhost:8080. Ainsi, lorsque j'essaie d'appeler l'API de repos depuis le front-end, il n'y a aucune chance que le navigateur me laisse recevoir une réponse du back-end de Spring sans les paramètres CORS appropriés. CORS peut être utilisé pour relâcher la protection Cross Domain script (XSS) que les navigateurs modernes ont. Si je comprends bien, les navigateurs protègent votre SPA contre une attaque par un XSS. Bien sûr, certaines réponses sur StackOverflow suggèrent d'ajouter un plugin chrome pour désactiver la protection XSS mais cela ne fonctionne pas vraiment ET si c'était le cas, cela ne ferait que repousser l'inévitable problème à plus tard.
Configuration CORS du backend
Voici comment vous devez configurer CORS dans votre application Spring Boot :
Ajouter une classe CorsFilter pour ajouter les en-têtes appropriés dans la réponse à une demande du client. Access-Control-Allow-Origin et Access-Control-Allow-Headers sont les éléments les plus importants à avoir pour l'authentification de base.
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);
}
...
}
Ajouter une classe de configuration qui étend Spring WebSecurityConfigurationAdapter. Dans cette classe, vous allez injecter votre filtre 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());
}
...
}
Vous n'avez pas besoin de mettre quoi que ce soit en rapport avec CORS dans votre contrôleur.
Frontend
Maintenant, dans le frontend, vous devez créer votre requête axios avec l'en-tête d'autorisation :
<!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>
J'espère que cela vous aidera.