部署后Spring Boot应用如何绕过CORS策略?多种尝试均失败
Spring Boot 3 + Angular 15 CORS问题求助
我开发了一个小型网站,采用Spring Boot 3作为后端、Angular 15作为前端,目前遇到CORS问题,前端无法与后端通信。查阅大量资料并尝试多种方案均未成功。
已尝试的解决方案
尝试1:在Security Config中添加CORS配置Bean
@Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(Arrays.asList("*")); configuration.setAllowedMethods(Arrays.asList("*")); configuration.setAllowedHeaders(List.of("*")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; }
尝试2:在Security Config中添加另一个CORS配置Bean
@Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(Arrays.asList("*")); configuration.setAllowedMethods(Arrays.asList("*")); configuration.setAllowCredentials(true); // 添加相关CORS响应头 configuration.addAllowedOrigin("*"); configuration.addAllowedHeader("*"); configuration.addAllowedMethod("*"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; }
尝试3:为控制器类添加@CrossOrigin注解
import org.springframework.web.bind.annotation.CrossOrigin; @RestController @RequestMapping("/api/v1/productcategory") @CrossOrigin public class ProductCategoryController { @Autowired ProductCategoryService productCategoryService; @GetMapping public ResponseEntity<List<ProductCategory>> get(){ return ResponseEntity.ok(productCategoryService.getAll()); } @PostMapping public ResponseEntity<String> post(){ return ResponseEntity.ok("POST: Hello Management"); } @PutMapping public ResponseEntity<String> put(){ return ResponseEntity.ok("PUT: Hello Management"); } @DeleteMapping public ResponseEntity<String> delete(){ return ResponseEntity.ok("DELETE: Hello Management"); } }
尝试4:在FilterChain中手动添加CORS响应头
@Override protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull FilterChain filterChain) throws ServletException, IOException { response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin")); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me"); final String authHeader = request.getHeader("Authorization"); final String jwt; final String userEmail; if(authHeader == null || !authHeader.startsWith("Bearer ")) { filterChain.doFilter(request, response); return; } jwt = authHeader.substring(7); userEmail = jwtService.extractUsername(jwt); if(userEmail !=null && SecurityContextHolder.getContext().getAuthentication() == null) { UserDetails userDetails = this.userDetailsService.loadUserByUsername(userEmail); var isTokenValid = tokenRepository.findByToken(jwt) .map(t -> !t.isExpired() && !t.isRevoked()) .orElse(false); if(jwtService.isTokenValid(jwt, userDetails) && isTokenValid) { UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(authToken); } } filterChain.doFilter(request, response); }
补充说明
后端使用JWT令牌进行身份验证和授权。
Angular端配置的HttpInterceptor
import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpResponse, HttpErrorResponse } from '@angular/common/http'; import { Observable, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; @Injectable() export class RequestInterceptorInterceptor implements HttpInterceptor { constructor() {} intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { if (request.method !== 'OPTIONS') { const jwtString = localStorage.getItem('jwt'); const jwtToken = jwtString ? JSON.parse(jwtString)?.jwt as string : ''; const authorizationHeader = `Bearer ${jwtToken}`; request = request.clone({ headers: request.headers.set('Authorization', authorizationHeader)}); } return next.handle(request).pipe( catchError((error: HttpErrorResponse) => { // 捕获错误并执行相应操作 if (error.status === 0 && error.statusText === 'Unknown Error') { console.log('Es ist ein CORS-Fehler aufgetreten'); // 执行更多操作... } // 将错误继续抛出,传递给调用者 return throwError(error); }) ); } }
错误日志截图

所有尝试都无法通过预检请求,请问哪里出错了?还有什么可尝试的方法能让前后端正常通信?
内容的提问来源于stack exchange,提问作者Doncarlito87
相关产品推荐
相关产品推荐

