Aus bestimmten Gründen blockiert dieses einfache Problem viele Entwickler. Ich hatte viele Stunden mit dieser einfachen Sache zu kämpfen. Dieses Problem so viele Dimensionen:
- CORS (wenn Sie ein Frontend und ein Backend für verschiedene Domänen und Ports verwenden.
- Backend-CORS-Konfiguration
- Grundlegende Authentifizierungskonfiguration von Axios
CORS
Mein Setup für die Entwicklung ist mit einer vuejs-Webpack-Anwendung, die auf localhost: 8081 ausgeführt wird, und einer Spring-Boot-Anwendung, die auf localhost: 8080 ausgeführt wird. Wenn Sie also versuchen, die Rest-API vom Frontend aus aufzurufen, kann der Browser ohne die richtigen CORS-Einstellungen keine Antwort vom Spring-Backend erhalten. Mit CORS kann der XSS-Schutz (Cross Domain Script) moderner Browser gelockert werden. Soweit ich weiß, schützen Browser Ihr SPA vor einem Angriff durch ein XSS. Natürlich schlugen einige Antworten auf StackOverflow vor, ein Chrome-Plugin hinzuzufügen, um den XSS-Schutz zu deaktivieren, aber dies funktioniert wirklich UND wenn dies der Fall wäre, würde das unvermeidliche Problem nur für später verschoben.
Backend-CORS-Konfiguration
So sollten Sie CORS in Ihrer Spring Boot-App einrichten:
Fügen Sie eine CorsFilter-Klasse hinzu, um der Antwort auf eine Clientanforderung die richtigen Header hinzuzufügen. Access-Control-Allow-Origin und Access-Control-Allow-Header sind das Wichtigste für die Basisauthentifizierung.
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);
}
...
}
Fügen Sie eine Konfigurationsklasse hinzu, die Spring WebSecurityConfigurationAdapter erweitert. In dieser Klasse injizieren Sie Ihren CORS-Filter:
@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());
}
...
}
Sie müssen nichts in Bezug auf CORS in Ihren Controller einfügen.
Vorderes Ende
Jetzt müssen Sie im Frontend Ihre Axios-Abfrage mit dem Authorization-Header erstellen:
<!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>
Hoffe das hilft.