diff --git a/build.gradle b/build.gradle index 8eeaccb..1e7257d 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,6 @@ dependencies { compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' implementation 'org.projectlombok:lombok' - implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2' // test testImplementation 'org.springframework.boot:spring-boot-starter-test' @@ -52,6 +51,9 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-validation' //REDIS implementation 'org.redisson:redisson-spring-boot-starter:3.19.0' + // SWAGGER + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' + testImplementation 'org.springframework.security:spring-security-test' testImplementation 'org.awaitility:awaitility:4.3.0' diff --git a/src/main/java/com/example/gtable/bookmark/controller/BookmarkController.java b/src/main/java/com/example/gtable/bookmark/controller/BookmarkController.java index 50fc835..c806830 100644 --- a/src/main/java/com/example/gtable/bookmark/controller/BookmarkController.java +++ b/src/main/java/com/example/gtable/bookmark/controller/BookmarkController.java @@ -15,14 +15,20 @@ import com.example.gtable.global.api.ApiUtils; import com.example.gtable.global.security.oauth2.dto.CustomOAuth2User; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; - +@Tag(name = "Bookmark API", description = "북마크 API") @RestController @RequestMapping("/bookmarks") @RequiredArgsConstructor public class BookmarkController { private final BookmarkService bookmarkService; + @PostMapping("/{storeId}") + @Operation(summary = "북마크 생성", description = "특정 주점에 대한 북마크 생성") + @ApiResponse(responseCode = "201", description = "북마크 생성") public ResponseEntity createBookmark(@PathVariable Long storeId,@AuthenticationPrincipal CustomOAuth2User customOAuth2User) { BookmarkCreateResponse response = bookmarkService.createBookmark(storeId,customOAuth2User); @@ -35,6 +41,8 @@ public ResponseEntity createBookmark(@PathVariable Long storeId,@Authenticati ); } @GetMapping + @Operation(summary = "북마크 조회", description = "내가 북마크한 주점 조회") + @ApiResponse(responseCode = "200", description = "북마크 조회") public ResponseEntity getAllBookmarks(@AuthenticationPrincipal CustomOAuth2User customOAuth2User) { return ResponseEntity .ok() @@ -45,6 +53,8 @@ public ResponseEntity getAllBookmarks(@AuthenticationPrincipal CustomOAuth2Us ); } @DeleteMapping("/{bookmarkId}") + @Operation(summary = "북마크 삭제", description = "특정 주점에 대한 북마크 삭제") + @ApiResponse(responseCode = "200", description = "북마크 삭제") public ResponseEntity deleteBookmark(@PathVariable Long bookmarkId, @AuthenticationPrincipal CustomOAuth2User customOAuth2User) { return ResponseEntity .ok() diff --git a/src/main/java/com/example/gtable/global/config/CorsConfig.java b/src/main/java/com/example/gtable/global/config/CorsConfig.java index 1c02f40..f82db1c 100644 --- a/src/main/java/com/example/gtable/global/config/CorsConfig.java +++ b/src/main/java/com/example/gtable/global/config/CorsConfig.java @@ -15,7 +15,7 @@ public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); // 쿠키나 인증헤더 자격증명 허용 - config.setAllowedOrigins(List.of("http://localhost:3000")); // 허용할 출처 설정 + config.setAllowedOrigins(List.of("http://localhost:3000", "http://localhost:8083")); // 허용할 출처 설정 config.setAllowedMethods(List.of("GET", "POST", "PATCH", "PUT", "DELETE", "OPTIONS")); // 메서드 허용 config.setAllowedHeaders(List.of("*")); //클라이언트가 보낼 수 있는 헤더 config.setExposedHeaders(List.of("Authorization")); //클라이언트(브라우저)가 접근할 수 있는 헤더 지정 diff --git a/src/main/java/com/example/gtable/global/config/SecurityConfig.java b/src/main/java/com/example/gtable/global/config/SecurityConfig.java index eb4d750..bdbf243 100644 --- a/src/main/java/com/example/gtable/global/config/SecurityConfig.java +++ b/src/main/java/com/example/gtable/global/config/SecurityConfig.java @@ -58,7 +58,15 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { "/login/oauth2/code/**", // 카카오 인증 콜백 "/api/refresh-token", // refresh token (토큰 갱신) "/api/users/signup", - "/api/users/login") + "/api/users/login", + "/swagger-ui/**", + "/v3/api-docs/**", + "/v3/api-docs.json", + "/api-docs/**", + "/swagger-resources/**", + "/webjars/**", + "/demo-ui.html" + ) .permitAll() .anyRequest().authenticated() // 그외 요청은 허가된 사람만 인가 ) diff --git a/src/main/java/com/example/gtable/global/config/SwaggerConfig.java b/src/main/java/com/example/gtable/global/config/SwaggerConfig.java new file mode 100644 index 0000000..aa47af2 --- /dev/null +++ b/src/main/java/com/example/gtable/global/config/SwaggerConfig.java @@ -0,0 +1,30 @@ +package com.example.gtable.global.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; + +@Configuration +public class SwaggerConfig { + + @Bean + public OpenAPI openAPI() { + return new OpenAPI() + .addSecurityItem(new SecurityRequirement().addList("JWT")) + .components(new Components() + .addSecuritySchemes("JWT", new SecurityScheme() + .name("Authorization") + .type(SecurityScheme.Type.HTTP) + .scheme("bearer") + .bearerFormat("JWT") + .in(SecurityScheme.In.HEADER))) + .info(new Info().title("NOWAIT API") + .description("NOWAIT API Specification") + .version("v0.0.1")); + } +} diff --git a/src/main/java/com/example/gtable/global/security/exception/GlobalExceptionHandler.java b/src/main/java/com/example/gtable/global/security/exception/GlobalExceptionHandler.java index 79af345..fd6269d 100644 --- a/src/main/java/com/example/gtable/global/security/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/example/gtable/global/security/exception/GlobalExceptionHandler.java @@ -7,6 +7,7 @@ import java.util.Map; import java.util.stream.Collectors; +import org.springframework.context.annotation.Profile; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.validation.FieldError; @@ -21,6 +22,7 @@ import lombok.extern.slf4j.Slf4j; @Slf4j +@Profile("!swagger") // 또는 커스텀 조건 @RestControllerAdvice public class GlobalExceptionHandler {