ด้วยเหตุผลบางประการปัญหาง่ายๆนี้คือการบล็อกนักพัฒนาจำนวนมาก ฉันต่อสู้กับสิ่งง่ายๆนี้มาหลายชั่วโมง ปัญหานี้มีหลายมิติ:
- CORS (หากคุณใช้ส่วนหน้าและแบ็กเอนด์บนโดเมนและพอร์ตต่างๆ
- การกำหนดค่าแบ็กเอนด์ CORS
- การกำหนดค่าการพิสูจน์ตัวตนพื้นฐานของ Axios
CORS
การตั้งค่าของฉันสำหรับการพัฒนาคือแอปพลิเคชัน vuejs webpack ที่ทำงานบน localhost: 8081 และแอปพลิเคชัน spring boot ที่ทำงานบน localhost: 8080 ดังนั้นเมื่อพยายามเรียก API ส่วนที่เหลือจากส่วนหน้าไม่มีทางที่เบราว์เซอร์จะให้ฉันได้รับการตอบกลับจากแบ็กเอนด์สปริงโดยไม่มีการตั้งค่า CORS ที่เหมาะสม CORS สามารถใช้เพื่อผ่อนคลายการป้องกัน Cross Domain Script (XSS) ที่เบราว์เซอร์รุ่นใหม่มี ตามที่ฉันเข้าใจแล้วเบราว์เซอร์กำลังปกป้อง SPA ของคุณจากการถูกโจมตีโดย XSS แน่นอนคำตอบบางอย่างใน StackOverflow แนะนำให้เพิ่มปลั๊กอิน Chrome เพื่อปิดใช้งานการป้องกัน XSS แต่วิธีนี้ใช้งานได้จริงและถ้าเป็นเช่นนั้นจะผลักปัญหาที่หลีกเลี่ยงไม่ได้ในภายหลังเท่านั้น
การกำหนดค่าแบ็กเอนด์ CORS
นี่คือวิธีที่คุณควรตั้งค่า CORS ในแอพ spring boot ของคุณ:
เพิ่มคลาส 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 ในคอนโทรลเลอร์ของคุณ
ส่วนหน้า
ตอนนี้ในส่วนหน้าคุณต้องสร้างแบบสอบถามแกนของคุณด้วยส่วนหัวการอนุญาต:
<!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>
หวังว่านี่จะช่วยได้