Spring Boot中的跨域資源共享(CORS)處理

省赚客开发者团队發表於2024-08-15

Spring Boot中的跨域資源共享(CORS)處理

大家好,我是微賺淘客返利系統3.0的小編,是個冬天不穿秋褲,天冷也要風度的程式猿!

在Web應用開發中,跨域資源共享(CORS)是一個常見的問題。當一個Web應用需要與另一個域下的Web服務進行互動時,瀏覽器出於安全考慮,會預設阻止這種跨域請求。Spring Boot作為目前流行的Java Web應用開發框架,提供了多種方式來處理CORS問題。

CORS 基本概念

CORS是一個W3C標準,全稱是"Cross-Origin Resource Sharing"。它允許Web應用在遵守同源策略的前提下,安全地訪問跨域資源。

Spring Boot 中的 CORS 處理

Spring Boot提供了幾種方式來處理CORS,包括使用註解、配置類和全域性配置。

使用 @CrossOrigin 註解

在Spring Boot中,可以透過@CrossOrigin註解來允許特定源的跨域請求。這個註解可以應用於類或方法上。

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@CrossOrigin(origins = "http://example.com")
@RestController
public class MyController {

    @GetMapping("/api/data")
    public String getData() {
        return "Data from server";
    }
}

使用 WebMvcConfigurer 配置 CORS

透過實現WebMvcConfigurer介面,可以在Spring Boot中自定義CORS配置。

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins("http://example.com")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*")
                .allowCredentials(true);
    }
}

全域性 CORS 配置

Spring Boot 2.2 版本開始,提供了一種更簡單的全域性CORS配置方式。

# application.properties
spring.web.cors.allow-credentials=true
spring.web.cors.allowed-origins=http://example.com
spring.web.cors.allowed-methods=GET,POST,PUT,DELETE
spring.web.cors.allowed-headers=*

使用 HttpSecurity 配置 CORS

在Spring Security中,也可以透過配置HttpSecurity來處理CORS。

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and()
            // 其他配置...
            .csrf().disable();
    }
}

自定義 CORS 過濾器

如果需要更復雜的CORS處理邏輯,可以自定義一個CORS過濾器。

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomCorsFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "http://example.com");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN");
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }
}

CORS 預請求

瀏覽器在傳送實際的跨域請求之前,會先傳送一個預請求(OPTIONS請求),以確認伺服器是否允許跨域請求。Spring Boot可以透過配置來簡化這個過程。

CORS 與 Spring Security 結合使用

在使用Spring Security的情況下,CORS的處理需要與Spring Security的配置結合。

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.cors.CorsConfigurationSource;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final CorsConfigurationSource corsConfigurationSource;

    public SecurityConfig(CorsConfigurationSource corsConfigurationSource) {
        this.corsConfigurationSource = corsConfigurationSource;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and()
            // 其他配置...
            .csrf().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 認證管理器配置...
    }
}

CORS 與 Zuul 結合使用

在使用Zuul作為API閘道器時,CORS的處理可以在Zuul中進行。

zuul:
  routes:
    myService:
      path: /myService/**
      serviceId: my-service
  cors:
    allowed-origins: "*"
    allowed-methods: GET,POST,PUT,DELETE
    allowed-headers: "*"
    expose-headers: "*"

CORS 與 Spring Cloud Gateway 結合使用

在使用Spring Cloud Gateway時,可以透過全域性過濾器來處理CORS。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class GatewayConfig {

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

總結

本文介紹了Spring Boot中處理CORS的多種方法,包括使用註解、配置類、全域性配置、自定義過濾器以及與Spring Security、Zuul和Spring Cloud Gateway的結合使用。透過這些方法,開發者可以根據實際需求靈活地處理跨域問題,提高Web應用的安全性和可用性。

本文著作權歸聚娃科技微賺淘客系統開發者團隊,轉載請註明出處!

相關文章