From f141d593eebb00bc1469986123e0bea106cfca15 Mon Sep 17 00:00:00 2001 From: teddy Date: Mon, 15 Dec 2025 15:47:25 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=EC=8A=A4=EC=9B=A8=EA=B1=B0=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=8C=8C=EC=9D=BC=EB=B3=84=20url=20=EB=B3=B4=EC=9D=B4?= =?UTF-8?q?=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cd/kamcoback/config/OpenApiConfig.java | 46 ++++++++++++------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/config/OpenApiConfig.java b/src/main/java/com/kamco/cd/kamcoback/config/OpenApiConfig.java index 3f8623ef..8e5051ac 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/OpenApiConfig.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/OpenApiConfig.java @@ -6,16 +6,30 @@ import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; import io.swagger.v3.oas.models.servers.Server; +import java.util.ArrayList; import java.util.List; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class OpenApiConfig { + @Value("${server.port}") + private String serverPort; + + @Value("${spring.profiles.active:local}") + private String profile; + + @Value("${swagger.dev-url:https://kamco.dev-api.gs.dabeeo.com}") + private String devUrl; + + @Value("${swagger.prod-url:https://api.kamco.com}") + private String prodUrl; + @Bean public OpenAPI kamcoOpenAPI() { - // ๐Ÿ”น 1) SecurityScheme ์ •์˜ (Bearer JWT) + // 1) SecurityScheme ์ •์˜ (Bearer JWT) SecurityScheme bearerAuth = new SecurityScheme() .type(SecurityScheme.Type.HTTP) @@ -24,12 +38,21 @@ public class OpenApiConfig { .in(SecurityScheme.In.HEADER) .name("Authorization"); - // ๐Ÿ”น 2) SecurityRequirement (๊ธฐ๋ณธ์œผ๋กœ BearerAuth ์‚ฌ์šฉ) + // 2) SecurityRequirement (๊ธฐ๋ณธ์œผ๋กœ BearerAuth ์‚ฌ์šฉ) SecurityRequirement securityRequirement = new SecurityRequirement().addList("BearerAuth"); - // ๐Ÿ”น 3) Components ์— SecurityScheme ๋“ฑ๋ก + // 3) Components ์— SecurityScheme ๋“ฑ๋ก Components components = new Components().addSecuritySchemes("BearerAuth", bearerAuth); + // profile ๋ณ„ server url ๋ถ„๊ธฐ + List servers = new ArrayList<>(); + switch (profile) { + case "prod" -> servers.add(new Server().url(prodUrl).description("์šด์˜ ์„œ๋ฒ„")); + case "dev" -> servers.add(new Server().url(devUrl).description("๊ฐœ๋ฐœ ์„œ๋ฒ„")); + default -> + servers.add(new Server().url("http://localhost:" + serverPort).description("๋กœ์ปฌ ๊ฐœ๋ฐœ ์„œ๋ฒ„")); + } + return new OpenAPI() .info( new Info() @@ -38,19 +61,10 @@ public class OpenApiConfig { "KAMCO ๋ณ€ํ™” ํƒ์ง€ ์‹œ์Šคํ…œ API ๋ฌธ์„œ\n\n" + "์ด API๋Š” ์ง€๋ฆฌ๊ณต๊ฐ„ ๋ฐ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•œ ๋ณ€ํ™” ํƒ์ง€ ์‹œ์Šคํ…œ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.\n" + "GeoJSON ํ˜•์‹์˜ ๊ณต๊ฐ„ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ฉฐ, PostgreSQL/PostGIS ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.") - .version("v1.0.0") - // .contact(new Contact().name("KAMCO Development - // Team").email("dev@kamco.com").url("https://kamco.com")) - // .license(new License().name("Proprietary").url("https://kamco.com/license")) - ) - .servers( - List.of( - new Server().url("http://localhost:8080").description("๋กœ์ปฌ ๊ฐœ๋ฐœ ์„œ๋ฒ„"), - new Server().url("https://kamco.dev-api.gs.dabeeo.com").description("๊ฐœ๋ฐœ ์„œ๋ฒ„") - // , new Server().url("https://api.kamco.com").description("์šด์˜ ์„œ๋ฒ„") - )) - .components(new Components()) - // ๐Ÿ”ฅ ์—ฌ๊ธฐ ํ•œ ์ค„์ด "๋ชจ๋“  API ๊ธฐ๋ณธ์ ์œผ๋กœ BearerAuth ์š”๊ตฌ" ์˜๋ฏธ + .version("v1.0.0")) + .servers(servers) + // ๋งŒ๋“ค์–ด๋‘” components๋ฅผ ๋„ฃ์–ด์•ผ ํ•จ + .components(components) .addSecurityItem(securityRequirement); } } From 9249c0f46049d59164171d726eb78ba8535e5b9d Mon Sep 17 00:00:00 2001 From: teddy Date: Mon, 15 Dec 2025 16:11:30 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=EC=8B=9C=20pend?= =?UTF-8?q?ing=20=EC=83=81=ED=83=9C=EC=9D=BC=EB=95=8C=EB=8F=84=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=EC=A0=95=EB=B3=B4=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cd/kamcoback/members/AuthController.java | 146 +++++++++--------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/members/AuthController.java b/src/main/java/com/kamco/cd/kamcoback/members/AuthController.java index f21a02c8..ffe785e3 100644 --- a/src/main/java/com/kamco/cd/kamcoback/members/AuthController.java +++ b/src/main/java/com/kamco/cd/kamcoback/members/AuthController.java @@ -55,55 +55,55 @@ public class AuthController { @Operation(summary = "๋กœ๊ทธ์ธ", description = "์‚ฌ๋ฒˆ์œผ๋กœ ๋กœ๊ทธ์ธํ•˜์—ฌ ์•ก์„ธ์Šค/๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์„ ๋ฐœ๊ธ‰.") @ApiResponses({ @ApiResponse( - responseCode = "200", - description = "๋กœ๊ทธ์ธ ์„ฑ๊ณต", - content = @Content(schema = @Schema(implementation = TokenResponse.class))), + responseCode = "200", + description = "๋กœ๊ทธ์ธ ์„ฑ๊ณต", + content = @Content(schema = @Schema(implementation = TokenResponse.class))), @ApiResponse( - responseCode = "401", - description = "๋กœ๊ทธ์ธ ์‹คํŒจ (์•„์ด๋””/๋น„๋ฐ€๋ฒˆํ˜ธ ์˜ค๋ฅ˜, ๊ณ„์ •์ž ๊ธˆ ๋“ฑ)", - content = - @Content( - schema = @Schema(implementation = ErrorResponse.class), - examples = { - @ExampleObject( - name = "์•„์ด๋”” ์ž…๋ ฅ ์˜ค๋ฅ˜", - description = "์กด์žฌํ•˜์ง€ ์•Š๋Š” ์•„์ด๋””", - value = - """ + responseCode = "401", + description = "๋กœ๊ทธ์ธ ์‹คํŒจ (์•„์ด๋””/๋น„๋ฐ€๋ฒˆํ˜ธ ์˜ค๋ฅ˜, ๊ณ„์ •์ž ๊ธˆ ๋“ฑ)", + content = + @Content( + schema = @Schema(implementation = ErrorResponse.class), + examples = { + @ExampleObject( + name = "์•„์ด๋”” ์ž…๋ ฅ ์˜ค๋ฅ˜", + description = "์กด์žฌํ•˜์ง€ ์•Š๋Š” ์•„์ด๋””", + value = + """ { "code": "LOGIN_ID_NOT_FOUND", "message": "์•„์ด๋””๋ฅผ ์ž˜๋ชป ์ž…๋ ฅํ•˜์…จ์Šต๋‹ˆ๋‹ค." } """), - @ExampleObject( - name = "๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ ์˜ค๋ฅ˜ (4ํšŒ ์ดํ•˜)", - description = "์•„์ด๋””๋Š” ์ •์ƒ, ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ‹€๋ฆฐ ๊ฒฝ์šฐ", - value = - """ + @ExampleObject( + name = "๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ ์˜ค๋ฅ˜ (4ํšŒ ์ดํ•˜)", + description = "์•„์ด๋””๋Š” ์ •์ƒ, ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ‹€๋ฆฐ ๊ฒฝ์šฐ", + value = + """ { "code": "LOGIN_PASSWORD_MISMATCH", "message": "๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž˜๋ชป ์ž…๋ ฅํ•˜์…จ์Šต๋‹ˆ๋‹ค." } """), - @ExampleObject( - name = "๋น„๋ฐ€๋ฒˆํ˜ธ ์˜ค๋ฅ˜ ํšŸ์ˆ˜ ์ดˆ๊ณผ", - description = "๋น„๋ฐ€๋ฒˆํ˜ธ 5ํšŒ ์ด์ƒ ์˜ค๋ฅ˜๋กœ ๊ณ„์ • ์ž ๊น€", - value = - """ + @ExampleObject( + name = "๋น„๋ฐ€๋ฒˆํ˜ธ ์˜ค๋ฅ˜ ํšŸ์ˆ˜ ์ดˆ๊ณผ", + description = "๋น„๋ฐ€๋ฒˆํ˜ธ 5ํšŒ ์ด์ƒ ์˜ค๋ฅ˜๋กœ ๊ณ„์ • ์ž ๊น€", + value = + """ { "code": "LOGIN_PASSWORD_EXCEEDED", "message": "๋น„๋ฐ€๋ฒˆํ˜ธ ์˜ค๋ฅ˜ ํšŸ์ˆ˜๋ฅผ ์ดˆ๊ณผํ•˜์—ฌ ์ด์šฉํ•˜์‹ค ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋กœ๊ทธ์ธ ์˜ค๋ฅ˜์— ๋Œ€ํ•ด ๊ด€๋ฆฌ์ž์—๊ฒŒ ๋ฌธ์˜ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค." } """) - })) + })) }) public ApiResponseDto signin( - @io.swagger.v3.oas.annotations.parameters.RequestBody( - description = "๋กœ๊ทธ์ธ ์š”์ฒญ ์ •๋ณด", - required = true) - @RequestBody - SignInRequest request, - HttpServletResponse response) { + @io.swagger.v3.oas.annotations.parameters.RequestBody( + description = "๋กœ๊ทธ์ธ ์š”์ฒญ ์ •๋ณด", + required = true) + @RequestBody + SignInRequest request, + HttpServletResponse response) { // ์‚ฌ์šฉ์ž ์ƒํƒœ ์กฐํšŒ String status = authService.getUserStatus(request); @@ -111,14 +111,8 @@ public class AuthController { MembersDto.Member member = new MembersDto.Member(); authentication = - authenticationManager.authenticate( - new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword())); - - // PENDING ๋น„ํ™œ์„ฑ ์ƒํƒœ(์ƒˆ๋กœ์šด ํŒจ์Šค์›Œ๋“œ ์ž…๋ ฅ ํ•ด์•ผํ•จ) - if (StatusType.PENDING.getId().equals(status)) { - member.setEmployeeNo(request.getUsername()); - return ApiResponseDto.ok(new TokenResponse(status, null, null, member)); - } + authenticationManager.authenticate( + new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword())); String username = authentication.getName(); // UserDetailsService ์—์„œ ์‚ฌ์šฉํ•œ username @@ -127,17 +121,17 @@ public class AuthController { // Redis์— RefreshToken ์ €์žฅ (TTL = 7์ผ) refreshTokenService.save( - username, refreshToken, jwtTokenProvider.getRefreshTokenValidityInMs()); + username, refreshToken, jwtTokenProvider.getRefreshTokenValidityInMs()); // HttpOnly + Secure ์ฟ ํ‚ค์— RefreshToken ์ €์žฅ ResponseCookie cookie = - ResponseCookie.from(refreshCookieName, refreshToken) - .httpOnly(true) - .secure(refreshCookieSecure) - .path("/") - .maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs())) - .sameSite("Strict") - .build(); + ResponseCookie.from(refreshCookieName, refreshToken) + .httpOnly(true) + .secure(refreshCookieSecure) + .path("/") + .maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs())) + .sameSite("Strict") + .build(); response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString()); @@ -146,6 +140,12 @@ public class AuthController { member.setName(user.getMember().getName()); member.setEmployeeNo(user.getMember().getEmployeeNo()); + // PENDING ๋น„ํ™œ์„ฑ ์ƒํƒœ(์ƒˆ๋กœ์šด ํŒจ์Šค์›Œ๋“œ ์ž…๋ ฅ ํ•ด์•ผํ•จ) + if (StatusType.PENDING.getId().equals(status)) { + member.setEmployeeNo(request.getUsername()); + return ApiResponseDto.ok(new TokenResponse(status, accessToken, refreshToken, member)); + } + // ์ธ์ฆ ์„ฑ๊ณต ๋กœ๊ทธ์ธ ์‹œ๊ฐ„ ์ €์žฅ authService.saveLogin(UUID.fromString(username)); @@ -156,16 +156,16 @@ public class AuthController { @Operation(summary = "ํ† ํฐ ์žฌ๋ฐœ๊ธ‰", description = "๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์œผ๋กœ ์ƒˆ๋กœ์šด ์•ก์„ธ์Šค/๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์„ ์žฌ๋ฐœ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.") @ApiResponses({ @ApiResponse( - responseCode = "200", - description = "์žฌ๋ฐœ๊ธ‰ ์„ฑ๊ณต", - content = @Content(schema = @Schema(implementation = TokenResponse.class))), + responseCode = "200", + description = "์žฌ๋ฐœ๊ธ‰ ์„ฑ๊ณต", + content = @Content(schema = @Schema(implementation = TokenResponse.class))), @ApiResponse( - responseCode = "403", - description = "๋งŒ๋ฃŒ๋˜์—ˆ๊ฑฐ๋‚˜ ์œ ํšจํ•˜์ง€ ์•Š์€ ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ", - content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + responseCode = "403", + description = "๋งŒ๋ฃŒ๋˜์—ˆ๊ฑฐ๋‚˜ ์œ ํšจํ•˜์ง€ ์•Š์€ ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) public ResponseEntity refresh(String refreshToken, HttpServletResponse response) - throws AccessDeniedException { + throws AccessDeniedException { if (refreshToken == null || !jwtTokenProvider.isValidToken(refreshToken)) { throw new AccessDeniedException("๋งŒ๋ฃŒ๋˜์—ˆ๊ฑฐ๋‚˜ ์œ ํšจํ•˜์ง€ ์•Š์€ ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ ์ž…๋‹ˆ๋‹ค."); } @@ -182,17 +182,17 @@ public class AuthController { // Redis ๊ฐฑ์‹  refreshTokenService.save( - username, newRefreshToken, jwtTokenProvider.getRefreshTokenValidityInMs()); + username, newRefreshToken, jwtTokenProvider.getRefreshTokenValidityInMs()); // ์ฟ ํ‚ค ๊ฐฑ์‹  ResponseCookie cookie = - ResponseCookie.from(refreshCookieName, newRefreshToken) - .httpOnly(true) - .secure(refreshCookieSecure) - .path("/") - .maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs())) - .sameSite("Strict") - .build(); + ResponseCookie.from(refreshCookieName, newRefreshToken) + .httpOnly(true) + .secure(refreshCookieSecure) + .path("/") + .maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs())) + .sameSite("Strict") + .build(); response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString()); MembersDto.Member member = new MembersDto.Member(); @@ -203,12 +203,12 @@ public class AuthController { @Operation(summary = "๋กœ๊ทธ์•„์›ƒ", description = "ํ˜„์žฌ ์‚ฌ์šฉ์ž์˜ ํ† ํฐ์„ ๋ฌดํšจํ™”(๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ ์‚ญ์ œ)ํ•ฉ๋‹ˆ๋‹ค.") @ApiResponses({ @ApiResponse( - responseCode = "200", - description = "๋กœ๊ทธ์•„์›ƒ ์„ฑ๊ณต", - content = @Content(schema = @Schema(implementation = Void.class))) + responseCode = "200", + description = "๋กœ๊ทธ์•„์›ƒ ์„ฑ๊ณต", + content = @Content(schema = @Schema(implementation = Void.class))) }) public ApiResponseDto> logout( - Authentication authentication, HttpServletResponse response) { + Authentication authentication, HttpServletResponse response) { if (authentication != null) { String username = authentication.getName(); // Redis์—์„œ RefreshToken ์‚ญ์ œ @@ -217,13 +217,13 @@ public class AuthController { // ์ฟ ํ‚ค ์‚ญ์ œ (Max-Age=0) ResponseCookie cookie = - ResponseCookie.from(refreshCookieName, "") - .httpOnly(true) - .secure(refreshCookieSecure) - .path("/") - .maxAge(0) - .sameSite("Strict") - .build(); + ResponseCookie.from(refreshCookieName, "") + .httpOnly(true) + .secure(refreshCookieSecure) + .path("/") + .maxAge(0) + .sameSite("Strict") + .build(); response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString()); return ApiResponseDto.createOK(ResponseEntity.noContent().build()); From 052291d5c3bc1d699d9cfb2fe8271f2631a96ca2 Mon Sep 17 00:00:00 2001 From: teddy Date: Mon, 15 Dec 2025 16:11:46 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=EC=8B=9C=20pend?= =?UTF-8?q?ing=20=EC=83=81=ED=83=9C=EC=9D=BC=EB=95=8C=EB=8F=84=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=EC=A0=95=EB=B3=B4=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cd/kamcoback/members/AuthController.java | 134 +++++++++--------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/src/main/java/com/kamco/cd/kamcoback/members/AuthController.java b/src/main/java/com/kamco/cd/kamcoback/members/AuthController.java index ffe785e3..cd123a40 100644 --- a/src/main/java/com/kamco/cd/kamcoback/members/AuthController.java +++ b/src/main/java/com/kamco/cd/kamcoback/members/AuthController.java @@ -55,55 +55,55 @@ public class AuthController { @Operation(summary = "๋กœ๊ทธ์ธ", description = "์‚ฌ๋ฒˆ์œผ๋กœ ๋กœ๊ทธ์ธํ•˜์—ฌ ์•ก์„ธ์Šค/๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์„ ๋ฐœ๊ธ‰.") @ApiResponses({ @ApiResponse( - responseCode = "200", - description = "๋กœ๊ทธ์ธ ์„ฑ๊ณต", - content = @Content(schema = @Schema(implementation = TokenResponse.class))), + responseCode = "200", + description = "๋กœ๊ทธ์ธ ์„ฑ๊ณต", + content = @Content(schema = @Schema(implementation = TokenResponse.class))), @ApiResponse( - responseCode = "401", - description = "๋กœ๊ทธ์ธ ์‹คํŒจ (์•„์ด๋””/๋น„๋ฐ€๋ฒˆํ˜ธ ์˜ค๋ฅ˜, ๊ณ„์ •์ž ๊ธˆ ๋“ฑ)", - content = - @Content( - schema = @Schema(implementation = ErrorResponse.class), - examples = { - @ExampleObject( - name = "์•„์ด๋”” ์ž…๋ ฅ ์˜ค๋ฅ˜", - description = "์กด์žฌํ•˜์ง€ ์•Š๋Š” ์•„์ด๋””", - value = - """ + responseCode = "401", + description = "๋กœ๊ทธ์ธ ์‹คํŒจ (์•„์ด๋””/๋น„๋ฐ€๋ฒˆํ˜ธ ์˜ค๋ฅ˜, ๊ณ„์ •์ž ๊ธˆ ๋“ฑ)", + content = + @Content( + schema = @Schema(implementation = ErrorResponse.class), + examples = { + @ExampleObject( + name = "์•„์ด๋”” ์ž…๋ ฅ ์˜ค๋ฅ˜", + description = "์กด์žฌํ•˜์ง€ ์•Š๋Š” ์•„์ด๋””", + value = + """ { "code": "LOGIN_ID_NOT_FOUND", "message": "์•„์ด๋””๋ฅผ ์ž˜๋ชป ์ž…๋ ฅํ•˜์…จ์Šต๋‹ˆ๋‹ค." } """), - @ExampleObject( - name = "๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ ์˜ค๋ฅ˜ (4ํšŒ ์ดํ•˜)", - description = "์•„์ด๋””๋Š” ์ •์ƒ, ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ‹€๋ฆฐ ๊ฒฝ์šฐ", - value = - """ + @ExampleObject( + name = "๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ ์˜ค๋ฅ˜ (4ํšŒ ์ดํ•˜)", + description = "์•„์ด๋””๋Š” ์ •์ƒ, ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ‹€๋ฆฐ ๊ฒฝ์šฐ", + value = + """ { "code": "LOGIN_PASSWORD_MISMATCH", "message": "๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž˜๋ชป ์ž…๋ ฅํ•˜์…จ์Šต๋‹ˆ๋‹ค." } """), - @ExampleObject( - name = "๋น„๋ฐ€๋ฒˆํ˜ธ ์˜ค๋ฅ˜ ํšŸ์ˆ˜ ์ดˆ๊ณผ", - description = "๋น„๋ฐ€๋ฒˆํ˜ธ 5ํšŒ ์ด์ƒ ์˜ค๋ฅ˜๋กœ ๊ณ„์ • ์ž ๊น€", - value = - """ + @ExampleObject( + name = "๋น„๋ฐ€๋ฒˆํ˜ธ ์˜ค๋ฅ˜ ํšŸ์ˆ˜ ์ดˆ๊ณผ", + description = "๋น„๋ฐ€๋ฒˆํ˜ธ 5ํšŒ ์ด์ƒ ์˜ค๋ฅ˜๋กœ ๊ณ„์ • ์ž ๊น€", + value = + """ { "code": "LOGIN_PASSWORD_EXCEEDED", "message": "๋น„๋ฐ€๋ฒˆํ˜ธ ์˜ค๋ฅ˜ ํšŸ์ˆ˜๋ฅผ ์ดˆ๊ณผํ•˜์—ฌ ์ด์šฉํ•˜์‹ค ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋กœ๊ทธ์ธ ์˜ค๋ฅ˜์— ๋Œ€ํ•ด ๊ด€๋ฆฌ์ž์—๊ฒŒ ๋ฌธ์˜ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค." } """) - })) + })) }) public ApiResponseDto signin( - @io.swagger.v3.oas.annotations.parameters.RequestBody( - description = "๋กœ๊ทธ์ธ ์š”์ฒญ ์ •๋ณด", - required = true) - @RequestBody - SignInRequest request, - HttpServletResponse response) { + @io.swagger.v3.oas.annotations.parameters.RequestBody( + description = "๋กœ๊ทธ์ธ ์š”์ฒญ ์ •๋ณด", + required = true) + @RequestBody + SignInRequest request, + HttpServletResponse response) { // ์‚ฌ์šฉ์ž ์ƒํƒœ ์กฐํšŒ String status = authService.getUserStatus(request); @@ -111,8 +111,8 @@ public class AuthController { MembersDto.Member member = new MembersDto.Member(); authentication = - authenticationManager.authenticate( - new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword())); + authenticationManager.authenticate( + new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword())); String username = authentication.getName(); // UserDetailsService ์—์„œ ์‚ฌ์šฉํ•œ username @@ -121,17 +121,17 @@ public class AuthController { // Redis์— RefreshToken ์ €์žฅ (TTL = 7์ผ) refreshTokenService.save( - username, refreshToken, jwtTokenProvider.getRefreshTokenValidityInMs()); + username, refreshToken, jwtTokenProvider.getRefreshTokenValidityInMs()); // HttpOnly + Secure ์ฟ ํ‚ค์— RefreshToken ์ €์žฅ ResponseCookie cookie = - ResponseCookie.from(refreshCookieName, refreshToken) - .httpOnly(true) - .secure(refreshCookieSecure) - .path("/") - .maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs())) - .sameSite("Strict") - .build(); + ResponseCookie.from(refreshCookieName, refreshToken) + .httpOnly(true) + .secure(refreshCookieSecure) + .path("/") + .maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs())) + .sameSite("Strict") + .build(); response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString()); @@ -156,16 +156,16 @@ public class AuthController { @Operation(summary = "ํ† ํฐ ์žฌ๋ฐœ๊ธ‰", description = "๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์œผ๋กœ ์ƒˆ๋กœ์šด ์•ก์„ธ์Šค/๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์„ ์žฌ๋ฐœ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.") @ApiResponses({ @ApiResponse( - responseCode = "200", - description = "์žฌ๋ฐœ๊ธ‰ ์„ฑ๊ณต", - content = @Content(schema = @Schema(implementation = TokenResponse.class))), + responseCode = "200", + description = "์žฌ๋ฐœ๊ธ‰ ์„ฑ๊ณต", + content = @Content(schema = @Schema(implementation = TokenResponse.class))), @ApiResponse( - responseCode = "403", - description = "๋งŒ๋ฃŒ๋˜์—ˆ๊ฑฐ๋‚˜ ์œ ํšจํ•˜์ง€ ์•Š์€ ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ", - content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + responseCode = "403", + description = "๋งŒ๋ฃŒ๋˜์—ˆ๊ฑฐ๋‚˜ ์œ ํšจํ•˜์ง€ ์•Š์€ ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) public ResponseEntity refresh(String refreshToken, HttpServletResponse response) - throws AccessDeniedException { + throws AccessDeniedException { if (refreshToken == null || !jwtTokenProvider.isValidToken(refreshToken)) { throw new AccessDeniedException("๋งŒ๋ฃŒ๋˜์—ˆ๊ฑฐ๋‚˜ ์œ ํšจํ•˜์ง€ ์•Š์€ ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ ์ž…๋‹ˆ๋‹ค."); } @@ -182,17 +182,17 @@ public class AuthController { // Redis ๊ฐฑ์‹  refreshTokenService.save( - username, newRefreshToken, jwtTokenProvider.getRefreshTokenValidityInMs()); + username, newRefreshToken, jwtTokenProvider.getRefreshTokenValidityInMs()); // ์ฟ ํ‚ค ๊ฐฑ์‹  ResponseCookie cookie = - ResponseCookie.from(refreshCookieName, newRefreshToken) - .httpOnly(true) - .secure(refreshCookieSecure) - .path("/") - .maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs())) - .sameSite("Strict") - .build(); + ResponseCookie.from(refreshCookieName, newRefreshToken) + .httpOnly(true) + .secure(refreshCookieSecure) + .path("/") + .maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs())) + .sameSite("Strict") + .build(); response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString()); MembersDto.Member member = new MembersDto.Member(); @@ -203,12 +203,12 @@ public class AuthController { @Operation(summary = "๋กœ๊ทธ์•„์›ƒ", description = "ํ˜„์žฌ ์‚ฌ์šฉ์ž์˜ ํ† ํฐ์„ ๋ฌดํšจํ™”(๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ ์‚ญ์ œ)ํ•ฉ๋‹ˆ๋‹ค.") @ApiResponses({ @ApiResponse( - responseCode = "200", - description = "๋กœ๊ทธ์•„์›ƒ ์„ฑ๊ณต", - content = @Content(schema = @Schema(implementation = Void.class))) + responseCode = "200", + description = "๋กœ๊ทธ์•„์›ƒ ์„ฑ๊ณต", + content = @Content(schema = @Schema(implementation = Void.class))) }) public ApiResponseDto> logout( - Authentication authentication, HttpServletResponse response) { + Authentication authentication, HttpServletResponse response) { if (authentication != null) { String username = authentication.getName(); // Redis์—์„œ RefreshToken ์‚ญ์ œ @@ -217,13 +217,13 @@ public class AuthController { // ์ฟ ํ‚ค ์‚ญ์ œ (Max-Age=0) ResponseCookie cookie = - ResponseCookie.from(refreshCookieName, "") - .httpOnly(true) - .secure(refreshCookieSecure) - .path("/") - .maxAge(0) - .sameSite("Strict") - .build(); + ResponseCookie.from(refreshCookieName, "") + .httpOnly(true) + .secure(refreshCookieSecure) + .path("/") + .maxAge(0) + .sameSite("Strict") + .build(); response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString()); return ApiResponseDto.createOK(ResponseEntity.noContent().build());