[Swagger] Swagger 3 TypeError: Failed to fetch

Simple·2022년 8월 4일
1

트러블슈팅

목록 보기
8/13
post-thumbnail

발단: EC2 서버에서 프로젝트 실행 후 Swagger를 접속해 API를 테스트하려 했으나? 아래와 같은 에러 발견

많은 레퍼런스를 봤으나 내 상황과 맞는 사례는 없었고 그러다 Request URL을 보게 됐는데

원래는 https://www.example.com/(요청URL) 이런식으로 요청이 되어야 하는데
http://www.example.com/(요청URL) 이런식으로 http 요청으로 되고 있었다,,

분명 서버에 http -> https로 redirect설정도 했고 잘 작동하는데 무엇이 문제일까?

swagger2는 관련 해결이 몇 개 보였으나 swagger3는 레퍼런스가 부족했다,, 그러다 swagger github에 issue로 등록된 질문에 단서를 얻어 구체적인 설정을 할 수 있었는데

@Component
public class Workaround implements WebMvcOpenApiTransformationFilter {

    @Override
    public OpenAPI transform(OpenApiTransformationContext<HttpServletRequest> context) {
        OpenAPI openApi = context.getSpecification();
        Server localServer = new Server();
        localServer.setDescription("local");
        localServer.setUrl("http://localhost:8080");

        Server testServer = new Server();
        testServer.setDescription("dev");
        testServer.setUrl("https://www.example.com);
        openApi.setServers(Arrays.asList(localServer, testServer));
        return openApi;
    }

    @Override
    public boolean supports(DocumentationType documentationType) {
        return documentationType.equals(DocumentationType.OAS_30);
    }

먼저 Spring component로 등록해준뒤

@Configuration
@EnableWebMvc
public class SwaggerConfig {

    @Bean
    public Docket SwaggerApi() {
        Server serverLocal = new Server("local", "http://localhost:8080", "for local usages", Collections.emptyList(), Collections.emptyList());
        Server devServer = new Server("test", "https://www.example.com", "for testing", Collections.emptyList(), Collections.emptyList());
        return new Docket(DocumentationType.OAS_30)
                .servers(serverLocal,devServer)
                .securityContexts(Arrays.asList(securityContext()))
                .securitySchemes(Arrays.asList(apiKey()))
                .ignoredParameterTypes(AuthenticationPrincipal.class)
                .apiInfo(swaggerInfo()) // API Docu 및 작성자 정보 매핑
                .select()
                .apis(RequestHandlerSelectors.basePackage("example"))
                .paths(PathSelectors.any()) // controller package 전부
                .build()
                .useDefaultResponseMessages(false);
    }

Swagger config에 설정한 서버를 넣어주면된다.

여기서! Spring security와 corsFilter를 사용한다면?

cors설정을 할때 .addAllOrigin("*") 과 .allowCrededentials(true)를 동시에 사용할 수 없다.

그러므로 allowCredential이 true일 때 “Access-Control-Allow-Origin” 응답 헤더헤더를 설정 할 수 없기 때문에 특수 값인 "*"를 사용 못한다.

해결법:

addAllowedOrigin("") -> addAllowedOriginPattern("")으로 바꾸거나

OR

특정 주소만 허락하게 설정한다.

@Configuration
public class CorsConfig {

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOriginPattern("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");

        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }

}

 





아직까진 Swagger 2에 대한 레퍼런스가 많기 때문에 Swagger 2를 많이 사용하는 것 같다.
재사용성이 좋다해서 Swagger 3를 사용해봤는데 설정 및 에러 관련해서 레퍼런스는 다소 부족한듯 하다. 저와 같은 에러를 발견하면 빠르게 해결했으면 좋겠습니다.

profile
몰입하는 개발자

0개의 댓글