-
Notifications
You must be signed in to change notification settings - Fork 0
#10 카카오로그인구현-리팩토링 #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The head ref may contain hidden characters: "#10-\uCE74\uCE74\uC624\uB85C\uADF8\uC778\uAD6C\uD604"
Changes from 4 commits
94b5140
6488326
731c4a1
54efc75
4b81dba
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,23 +1,24 @@ | ||
| package com.example.gtable.global.api; | ||
|
|
||
| import lombok.Getter; | ||
| import org.springframework.http.HttpStatus; | ||
|
|
||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| public class ApiError { | ||
| private final String message; | ||
| private final int status; | ||
| private final String message; | ||
| private final int status; | ||
|
|
||
| public ApiError(String message, int status) { | ||
| this.message = message; | ||
| this.status = status; | ||
| } | ||
| public ApiError(String message, int status) { | ||
| this.message = message; | ||
| this.status = status; | ||
| } | ||
|
|
||
| public ApiError(Throwable throwable, HttpStatus status) { | ||
| this(throwable.getMessage(), status); | ||
| } | ||
| public ApiError(Throwable throwable, HttpStatus status) { | ||
| this(throwable.getMessage(), status); | ||
| } | ||
|
|
||
| public ApiError(String message, HttpStatus status) { | ||
| this(message, status.value()); | ||
| } | ||
| public ApiError(String message, HttpStatus status) { | ||
| this(message, status.value()); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,21 +1,21 @@ | ||
| package com.example.gtable.global.api; | ||
|
|
||
| public class ApiResult<T> { | ||
| private final boolean success; | ||
| private final T response; | ||
| private final ApiError error; | ||
| private final boolean success; | ||
| private final T response; | ||
| private final ApiError error; | ||
|
|
||
| public ApiResult(boolean success, T response, ApiError error) { | ||
| this.success = success; | ||
| this.response = response; | ||
| this.error = error; | ||
| } | ||
| public ApiResult(boolean success, T response, ApiError error) { | ||
| this.success = success; | ||
| this.response = response; | ||
| this.error = error; | ||
| } | ||
|
|
||
| public boolean isSuccess() { | ||
| return success; | ||
| } | ||
| public boolean isSuccess() { | ||
| return success; | ||
| } | ||
|
|
||
| public T getResponse() { | ||
| return response; | ||
| } | ||
| public T getResponse() { | ||
| return response; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,20 +1,21 @@ | ||
| package com.example.gtable.global.api; | ||
|
|
||
| import org.springframework.http.HttpStatus; | ||
|
|
||
| import lombok.AccessLevel; | ||
| import lombok.NoArgsConstructor; | ||
| import org.springframework.http.HttpStatus; | ||
|
|
||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
| public class ApiUtils { | ||
| public static <T> ApiResult<T> success(T response) { | ||
| return new ApiResult<>(true, response,null); | ||
| } | ||
| public static <T> ApiResult<T> success(T response) { | ||
| return new ApiResult<>(true, response, null); | ||
| } | ||
|
|
||
| public static ApiResult<?> error(Throwable throwable, HttpStatus status) { | ||
| return new ApiResult<>(false, null, new ApiError(throwable, status)); | ||
| } | ||
| public static ApiResult<?> error(Throwable throwable, HttpStatus status) { | ||
| return new ApiResult<>(false, null, new ApiError(throwable, status)); | ||
| } | ||
|
|
||
| public static ApiResult<?> error(String message,HttpStatus status) { | ||
| return new ApiResult<>(false, null, new ApiError(message,status)); | ||
| } | ||
| public static ApiResult<?> error(String message, HttpStatus status) { | ||
| return new ApiResult<>(false, null, new ApiError(message, status)); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,28 @@ | ||||||||||||||||||||||||
| package com.example.gtable.global.config; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| import java.util.List; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| import org.springframework.context.annotation.Bean; | ||||||||||||||||||||||||
| import org.springframework.context.annotation.Configuration; | ||||||||||||||||||||||||
| import org.springframework.web.cors.CorsConfiguration; | ||||||||||||||||||||||||
| import org.springframework.web.cors.CorsConfigurationSource; | ||||||||||||||||||||||||
| import org.springframework.web.cors.UrlBasedCorsConfigurationSource; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| @Configuration | ||||||||||||||||||||||||
| public class CorsConfig { | ||||||||||||||||||||||||
| @Bean | ||||||||||||||||||||||||
| public CorsConfigurationSource corsConfigurationSource() { | ||||||||||||||||||||||||
| CorsConfiguration config = new CorsConfiguration(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| config.setAllowCredentials(true); // 쿠키나 인증헤더 자격증명 허용 | ||||||||||||||||||||||||
| config.setAllowedOrigins(List.of("http://localhost:3000")); // 허용할 출처 설정 | ||||||||||||||||||||||||
| config.setAllowedMethods(List.of("GET", "POST", "PATCH", "PUT", "DELETE", "OPTIONS")); // 메서드 허용 | ||||||||||||||||||||||||
| config.setAllowedHeaders(List.of("*")); //클라이언트가 보낼 수 있는 헤더 | ||||||||||||||||||||||||
| config.setExposedHeaders(List.of("Authorization")); //클라이언트(브라우저)가 접근할 수 있는 헤더 지정 | ||||||||||||||||||||||||
| // config.setAllowCredentials(true); // 쿠키 포함 허용 | ||||||||||||||||||||||||
|
Comment on lines
+17
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion CORS 설정이 잘 구성되었으나 중복 코드와 보안 고려사항이 있습니다. 코드에서 발견된 개선점들:
다음과 같은 개선을 제안드립니다: config.setAllowCredentials(true); // 쿠키나 인증헤더 자격증명 허용
config.setAllowedOrigins(List.of("http://localhost:3000")); // 허용할 출처 설정
config.setAllowedMethods(List.of("GET", "POST", "PATCH", "PUT", "DELETE", "OPTIONS")); // 메서드 허용
config.setAllowedHeaders(List.of("*")); //클라이언트가 보낼 수 있는 헤더
config.setExposedHeaders(List.of("Authorization")); //클라이언트(브라우저)가 접근할 수 있는 헤더 지정
-// config.setAllowCredentials(true); // 쿠키 포함 허용📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); | ||||||||||||||||||||||||
| source.registerCorsConfiguration("/**", config); //** 뜻은 모든 URL 경로에 적용한다는 의미 | ||||||||||||||||||||||||
| return source; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,64 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package com.example.gtable.global.config; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.context.annotation.Bean; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.context.annotation.Configuration; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.security.config.http.SessionCreationPolicy; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.security.web.SecurityFilterChain; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.web.cors.CorsConfigurationSource; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.example.gtable.global.security.jwt.JwtAuthorizationFilter; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.example.gtable.global.security.jwt.JwtUtil; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.example.gtable.global.security.oauth2.CustomOAuth2UserService; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import lombok.RequiredArgsConstructor; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Configuration | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @EnableWebSecurity // security 활성화 어노테이션 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @RequiredArgsConstructor | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public class SecurityConfig { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private final CustomOAuth2UserService customOAuth2UserService; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private final com.example.gtable.global.security.oauth2.OAuth2LoginSuccessHandler OAuth2LoginSuccessHandler; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private final JwtUtil jwtUtil; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private final CorsConfigurationSource corsConfigurationSource; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Bean | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| http | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // CSRF 방어 기능 비활성화 (jwt 토큰을 사용할 것이기에 필요없음) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .csrf(AbstractHttpConfigurer::disable) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // 시큐리티 폼 로그인 비활성화 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .formLogin(AbstractHttpConfigurer::disable) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // HTTP Basic 인증 비활성화 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .httpBasic(AbstractHttpConfigurer::disable) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // oauth2 로그인 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // - userInfoEndPoint에서 사용자 정보 불러오고, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // - successHandler에서 로그인 성공 시 JWT 생성 및 반환로직 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .oauth2Login(oauth2 -> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| oauth2.userInfoEndpoint(userInfoEndpoint -> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| userInfoEndpoint.userService(customOAuth2UserService) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ).successHandler(OAuth2LoginSuccessHandler) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // 세션 사용하지 않음 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .sessionManagement(session -> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| session.sessionCreationPolicy(SessionCreationPolicy.STATELESS) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .authorizeHttpRequests(auth -> auth | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .requestMatchers( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "/oauth2/authorization/kakao", // 카카오 로그인 요청 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "/login/oauth2/code/**", // 카카오 인증 콜백 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "/api/refresh-token") // refresh token (토큰 갱신) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .permitAll() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .anyRequest().authenticated() // 그외 요청은 허가된 사람만 인가 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // JWTFiler | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .addFilterBefore(new JwtAuthorizationFilter(jwtUtil), UsernamePasswordAuthenticationFilter.class); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return http.build(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+27
to
+61
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CORS 설정 빈을 주입해두고 실제로 적용하지 않았습니다 - http
+ http
+ // CORS 설정 적용
+ .cors(cors -> cors.configurationSource(corsConfigurationSource))📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package com.example.gtable.global.security.exception; | ||
|
|
||
| public abstract class BusinessException extends RuntimeException { | ||
| private final ErrorMessage errorMessage; | ||
|
|
||
| protected BusinessException(ErrorMessage errorMessage) { | ||
| super(errorMessage.getMessage()); | ||
| this.errorMessage = errorMessage; | ||
| } | ||
|
|
||
| public String getCode() { | ||
| return errorMessage.getCode(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| package com.example.gtable.global.security.exception; | ||
|
|
||
| import lombok.Getter; | ||
| import lombok.RequiredArgsConstructor; | ||
|
|
||
| @Getter | ||
| @RequiredArgsConstructor | ||
| public enum ErrorMessage { | ||
| // global | ||
| INVALID_INPUT_VALUE("입력값이 올바르지 않습니다.", "g001"), | ||
|
|
||
| // auth | ||
| UNAUTHORIZED("권한이 없습니다", "a001"), | ||
|
|
||
| // token | ||
| REFRESH_TOKEN_NOT_FOUND("기존 리프레시 토큰을 찾을 수 없습니다.", "t001"), | ||
| DOES_NOT_MATCH_REFRESH_TOKEN("기존 리프레시 토큰이 일치하지 않습니다.", "t002"); | ||
|
|
||
| private final String message; | ||
| private final String code; | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package com.example.gtable.global.security.exception; | ||
|
|
||
| import java.util.HashMap; | ||
| import java.util.Map; | ||
|
|
||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| public class ErrorResponse { | ||
| private final String message; | ||
| private final String code; | ||
| private final Map<String, String> errors; | ||
|
|
||
| public ErrorResponse(String message, String code) { | ||
| this.message = message; | ||
| this.code = code; | ||
| errors = new HashMap<>(); | ||
| } | ||
|
|
||
| public ErrorResponse(String message, String code, Map<String, String> errors) { | ||
| this.message = message; | ||
| this.code = code; | ||
| this.errors = errors; | ||
| } | ||
|
|
||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
중복된 테스트 의존성을 발견했습니다.
31번 라인과 46번 라인에
spring-boot-starter-test의존성이 중복으로 선언되어 있습니다.다음과 같이 중복을 제거해주시기 바랍니다:
// Web MVC implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' -testImplementation 'org.springframework.boot:spring-boot-starter-test' // DB implementation 'org.springframework.boot:spring-boot-starter-data-jpa' runtimeOnly 'com.mysql:mysql-connector-j' // TEST testRuntimeOnly 'org.junit.platform:junit-platform-launcher' // ... (다른 의존성들) // SPRING SECURITY implementation 'org.springframework.boot:spring-boot-starter-security' testImplementation 'org.springframework.boot:spring-boot-starter-test'🤖 Prompt for AI Agents