【问题标题】:CORS with gateway带网关的 CORS
【发布时间】:2021-11-27 02:47:17
【问题描述】:

我必须使用 spring-boot 创建一些微服务。仅使用一个控制器创建 MailService 并配置 CORS:

package com.smdev.mailservice.controller;

import com.smdev.mailservice.model.dto.EmailAddress;
import com.smdev.mailservice.model.dto.SendMailDTO;
import com.smdev.mailservice.service.MailService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@Api
@RestController
@RequestMapping("/api/mail")
@CrossOrigin(origins = "*", methods = {RequestMethod.POST, RequestMethod.OPTIONS})
public class MailSendController {

    private final MailService mailService;

    @Autowired
    public MailSendController(MailService mailService) {
        this.mailService = mailService;
    }

    @ApiOperation(value = "Send message from 'Contact Us' form")
    @ApiResponses({
            @ApiResponse(code = 200, message = "E-Mail send successfully"),
            @ApiResponse(code = 400, message = "Invalid data sent", response = ResponseEntity.class)
    })
    @PostMapping(value = "/feedback", consumes = {MediaType.APPLICATION_JSON_VALUE})
    public void feedback(@Valid @RequestBody SendMailDTO sendMailDTO){
        mailService.sendMessage(sendMailDTO, EmailAddress.FEEDBACK);
    }

}

这里我也有GatewayService:

package com.smdev.gatewayservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class GatewayServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayServiceApplication.class, args);
    }

    @Bean
    public RouteLocator getRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
        return routeLocatorBuilder.routes()
                .route(p -> p
                        .path("/api/mail/**")
                        .uri("http://localhost:8001"))
                .build();
    }

}

此 API 将从 Angular 前端调用。当我使用 curl 调用 api 时:

curl -X POST -H "Content-type: application/json" -d '{some json data}' localhost:8000/api/mail/feedback

一切正常。但是当我从 FE 打电话时:

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from 'src/environments/environment';
import { ContactUs } from '../model/contact-us';

@Injectable({
  providedIn: 'root'
})
export class ApiService {

  constructor(private httpClient: HttpClient) { }

  sendContactUs(dto: ContactUs): Observable<any> {
    return this.httpClient.post(`${environment.apiUrl}/mail/feedback`, dto);
  }
}

我收到 CORS 错误。我认为原因是我必须在 GatewayService 中配置 CORS,但我没有找到相关信息。

这里没有使用 Spring-security

【问题讨论】:

    标签: java spring-boot cors microservices gateway


    【解决方案1】:

    尝试这样的事情(例如版本 spring-boot 2.4.9 和 spring-cloud 2020.0.3)

    在 spring-cloud-gateway 项目中添加此类在网关上处理 cors

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.HttpMethod;
    import org.springframework.web.cors.CorsConfiguration;
    import org.springframework.web.cors.reactive.CorsConfigurationSource;
    import org.springframework.web.cors.reactive.CorsWebFilter;
    import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
    
    @Configuration
    public class CorsConfig {
        
        @Bean
        public CorsWebFilter corsFilter() {
            return new CorsWebFilter(corsConfigurationSource());
        }
    
        @Bean
        public CorsConfigurationSource corsConfigurationSource() {
            final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            CorsConfiguration config = new CorsConfiguration().applyPermitDefaultValues();
            config.addAllowedMethod(HttpMethod.PUT);
            config.addAllowedMethod(HttpMethod.DELETE);
            config.addAllowedMethod(HttpMethod.GET);
            config.addAllowedMethod(HttpMethod.OPTIONS);
            config.addAllowedMethod(HttpMethod.POST);
    
            source.registerCorsConfiguration("/**", config);
            return source;
        }
    
    }
    
    

    在跨请求时检查cors上是否有重复值很重要

    
    return routeLocatorBuilder.routes()
                    .route(p -> p
                        .path("/api/mail/**")
                      
                        // something like this
                        .filters(f -> f.dedupeResponseHeader("Access-Control-Allow-Origin", "RETAIN_UNIQUE"))
                        .uri("http://localhost:8001")
                    )
                    .route( ... )
                    .route( ... )
                    .build();
    
    
    

    【讨论】:

    • 您可以继续在此处发布所有问题 :) 或查看我的个人资料以查找任何联系人,但我认为在这里发布会更快
    猜你喜欢
    • 2021-03-15
    • 2020-07-16
    • 1970-01-01
    • 2022-11-24
    • 2021-08-26
    • 2016-05-15
    • 2016-05-18
    • 2020-07-04
    • 2017-09-16
    相关资源
    最近更新 更多