Vì một số lý do, vấn đề đơn giản này đang chặn nhiều nhà phát triển. Tôi đã vật lộn nhiều giờ với điều đơn giản này. Vấn đề này theo nhiều chiều:
- CORS (nếu bạn đang sử dụng giao diện người dùng và phụ trợ trên các tên miền và cổng khác nhau.
- Cấu hình Backend CORS
- Cấu hình xác thực cơ bản của Axios
CORS
Thiết lập để phát triển của tôi là với một ứng dụng webpack vuejs chạy trên localhost: 8081 và một ứng dụng khởi động mùa xuân chạy trên localhost: 8080. Vì vậy, khi cố gắng gọi API nghỉ ngơi từ giao diện người dùng, không có cách nào mà trình duyệt cho phép tôi nhận được phản hồi từ chương trình phụ trợ mùa xuân mà không có cài đặt CORS thích hợp. CORS có thể được sử dụng để nới lỏng bảo vệ Tập lệnh tên miền chéo (XSS) mà các trình duyệt hiện đại có. Theo tôi hiểu điều này, các trình duyệt đang bảo vệ SPA của bạn khỏi bị tấn công bởi XSS. Tất nhiên, một số câu trả lời trên StackOverflow đề xuất thêm một plugin chrome để tắt tính năng bảo vệ XSS nhưng điều này thực sự hoạt động VÀ nếu có, sẽ chỉ đẩy vấn đề không thể tránh khỏi về sau.
Cấu hình CORS phụ trợ
Đây là cách bạn nên thiết lập CORS trong ứng dụng khởi động mùa xuân của mình:
Thêm một lớp CorsFilter để thêm các tiêu đề thích hợp trong phản hồi cho một yêu cầu của khách hàng. Access-Control-Allow-Origin và Access-Control-Allow-Headers là điều quan trọng nhất cần có để xác thực cơ bản.
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);
}
...
}
Thêm một lớp cấu hình mở rộng Spring WebSecurityConfigurationAdapter. Trong lớp này, bạn sẽ chèn bộ lọc CORS của mình:
@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());
}
...
}
Bạn không phải đặt bất cứ thứ gì liên quan đến CORS trong bộ điều khiển của mình.
Giao diện người dùng
Bây giờ, trong giao diện người dùng, bạn cần tạo truy vấn axios của mình với tiêu đề Ủy quyền:
<!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>
Hi vọng điêu nay co ich.