From a2bcfb79be3fee884a9db5b6d5cd85a0f49db77c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=83=81=ED=98=81?= <105288887+sangcci@users.noreply.github.com> Date: Mon, 25 Nov 2024 11:35:00 +0900 Subject: [PATCH] =?UTF-8?q?[ARV-36]=20feat:=20jwt=20swagger=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(#34)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/CustomAccessDeniedHandler.java | 9 +++- .../auth/util/JwtTestTokenInitializer.java | 27 +++++++++++ .../allreva/common/config/SwaggerConfig.java | 37 ++++++++++++++- .../runner/MemberDummyDataInitializer.java | 47 +++++++++++++++++++ 4 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/backend/allreva/auth/util/JwtTestTokenInitializer.java create mode 100644 src/main/java/com/backend/allreva/common/runner/MemberDummyDataInitializer.java diff --git a/src/main/java/com/backend/allreva/auth/exception/CustomAccessDeniedHandler.java b/src/main/java/com/backend/allreva/auth/exception/CustomAccessDeniedHandler.java index 030e3c89..d0eeb98f 100644 --- a/src/main/java/com/backend/allreva/auth/exception/CustomAccessDeniedHandler.java +++ b/src/main/java/com/backend/allreva/auth/exception/CustomAccessDeniedHandler.java @@ -32,7 +32,12 @@ public CustomAccessDeniedHandler( public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { Exception exception = (Exception) request.getAttribute("jakarta.servlet.error.exception"); - log.info("권한 없음 예외 발생: {}", exception); - resolver.resolveException(request, response, null, exception); + if (exception != null) { + log.info("권한 없음 예외 발생: {}", exception); + resolver.resolveException(request, response, null, exception); + } else { + log.info("권한 없음 예외 발생: {}", accessDeniedException); + resolver.resolveException(request, response, null, accessDeniedException); + } } } diff --git a/src/main/java/com/backend/allreva/auth/util/JwtTestTokenInitializer.java b/src/main/java/com/backend/allreva/auth/util/JwtTestTokenInitializer.java new file mode 100644 index 00000000..7e25be85 --- /dev/null +++ b/src/main/java/com/backend/allreva/auth/util/JwtTestTokenInitializer.java @@ -0,0 +1,27 @@ +package com.backend.allreva.auth.util; + + +import java.util.HashMap; +import java.util.Map; +import org.springframework.stereotype.Component; + +@Component +public class JwtTestTokenInitializer { + + private final Map jwtTokens; + + public JwtTestTokenInitializer(JwtProvider jwtProvider) { + this.jwtTokens = new HashMap<>(); + + jwtTokens.put("ADMIN", jwtProvider.generateRefreshToken(String.valueOf(1L))); + jwtTokens.put("USER", jwtProvider.generateRefreshToken(String.valueOf(2L))); + jwtTokens.put("GUEST", jwtProvider.generateRefreshToken(String.valueOf(3L))); + + jwtTokens.forEach((role, token) -> + System.out.println(role + " Token: " + token)); + } + + public String getToken(String role) { + return jwtTokens.get(role); + } +} diff --git a/src/main/java/com/backend/allreva/common/config/SwaggerConfig.java b/src/main/java/com/backend/allreva/common/config/SwaggerConfig.java index 6a714de3..37cd7dea 100644 --- a/src/main/java/com/backend/allreva/common/config/SwaggerConfig.java +++ b/src/main/java/com/backend/allreva/common/config/SwaggerConfig.java @@ -1,16 +1,49 @@ package com.backend.allreva.common.config; +import com.backend.allreva.auth.util.JwtTestTokenInitializer; +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; +import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration +@RequiredArgsConstructor public class SwaggerConfig { + private final JwtTestTokenInitializer jwtTestTokenInitializer; + @Bean - public OpenAPI openAPI() { + public OpenAPI customOpenAPI() { + SecurityScheme userScheme = createSecurityScheme("USER", jwtTestTokenInitializer.getToken("USER")); + SecurityScheme adminScheme = createSecurityScheme("ADMIN", jwtTestTokenInitializer.getToken("ADMIN")); + SecurityScheme guestScheme = createSecurityScheme("GUEST", jwtTestTokenInitializer.getToken("GUEST")); + + SecurityRequirement userRequirement = new SecurityRequirement().addList("USER"); + SecurityRequirement adminRequirement = new SecurityRequirement().addList("ADMIN"); + SecurityRequirement guestRequirement = new SecurityRequirement().addList("GUEST"); + return new OpenAPI() - .info(new Info().title("AllReva")); + .info(new Info().title("AllReva")) + .components(new Components() + .addSecuritySchemes("USER", userScheme) + .addSecuritySchemes("ADMIN", adminScheme) + .addSecuritySchemes("GUEST", guestScheme)) + .addSecurityItem(userRequirement) + .addSecurityItem(adminRequirement) + .addSecurityItem(guestRequirement); + } + + private SecurityScheme createSecurityScheme(String role, String token) { + return new SecurityScheme() + .type(SecurityScheme.Type.HTTP) + .scheme("bearer") + .bearerFormat("JWT") + .name("Authorization") + .description(String.format("%s Token: %s", role, token)) + .in(SecurityScheme.In.HEADER); } } diff --git a/src/main/java/com/backend/allreva/common/runner/MemberDummyDataInitializer.java b/src/main/java/com/backend/allreva/common/runner/MemberDummyDataInitializer.java new file mode 100644 index 00000000..5a4a3a21 --- /dev/null +++ b/src/main/java/com/backend/allreva/common/runner/MemberDummyDataInitializer.java @@ -0,0 +1,47 @@ +package com.backend.allreva.common.runner; + +import com.backend.allreva.common.model.Email; +import com.backend.allreva.member.command.application.MemberRepository; +import com.backend.allreva.member.command.domain.Member; +import com.backend.allreva.member.command.domain.value.LoginProvider; +import com.backend.allreva.member.command.domain.value.MemberRole; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class MemberDummyDataInitializer implements CommandLineRunner { + + private final MemberRepository memberRepository; + + @Override + public void run(String... args) throws Exception { + Member admin = Member.builder() + .email(Email.builder().email("admin@email.com").build()) + .nickname("admin") + .loginProvider(LoginProvider.GOOGLE) + .memberRole(MemberRole.ADMIN) + .introduce("test") + .profileImageUrl("https://my_picture") + .build(); + memberRepository.save(admin); + + Member user = Member.builder() + .email(Email.builder().email("user@email.com").build()) + .nickname("user") + .loginProvider(LoginProvider.GOOGLE) + .memberRole(MemberRole.USER) + .introduce("test") + .profileImageUrl("https://my_picture") + .build(); + memberRepository.save(user); + + Member guest = Member.createTemporary( + "guest@email.com", + "guest", + LoginProvider.GOOGLE, + "https://my_picture"); + memberRepository.save(guest); + } +}