diff --git a/README.md b/README.md
index e09c953..9b0bda0 100644
--- a/README.md
+++ b/README.md
@@ -1,22 +1,175 @@
# Orury!
+![orury_mockup](https://github.com/Kernel360/E2E1-Orury/assets/44130863/41f0692c-2c24-4709-9f05-aa05827e66be)
-당신만의 클라이밍 커뮤니티, 오루리
+
+당신만의 클라이밍 커뮤니티, 오루리!
+내 클라이밍 라이프를 다른 클라이머들과 공유하고, 즐기세요!
+
## 멤버
-|Backend| Backend |Backend|Backend|
-|:---:|:-----------------------------------------------------------------------------------------------------------------------------:|:---:|:---:|
-|| |||
-|[형준](https://github.com/kkkapuq)| [찬욱](https://github.com/mooncw) |[종민](https://github.com/ShineCorine)|[무룡](https://github.com/aqrms)|
+| Backend | Backend | Backend | Backend |
+|:-----------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------:|
+| | | | |
+| [형준](https://github.com/kkkapuq) | [찬욱](https://github.com/mooncw) | [종민](https://github.com/ShineCorine) | [무룡](https://github.com/aqrms) |
+| 팀원들이 본
**형준**은 | 팀원들이 본
**찬욱**은 | 팀원들이 본
**종민**은 | 팀원들이 본
**무룡**은 |
+| 중심을 잡아줘요
리더쉽이 강해요
솔선수범한 리더 | 다재다능 행동대장
뭐든지 꼼꼼해요
팀의 해결사 | 부딪히고 보는 진격의 개발자
꾸준하게 성장해요
실력이 쑥쑥자라요 | 끝까지 가면 내가이겨
어려운 일도 파고들어요
책임감이 강해요 |
## 기술 스택
-
+
## 서비스 흐름도
-![image](https://github.com/Kernel360/E2E1-Orury/assets/44130863/ef0c31d3-623a-4ef8-b9a8-2a8fe0e5706b)
+![서비스 흐름도](https://github.com/Kernel360/E2E1-Orury/assets/44130863/20cd677f-370a-4312-a271-73a25436069d)
## CI/CD
-![image](https://github.com/Kernel360/E2E1-Orury/assets/44130863/23132200-f87c-4137-ad4b-6227a6174caa)
+![image](https://github.com/Kernel360/E2E1-Orury/assets/44130863/d928aeb7-02e3-4909-96da-1bf31734ef4f)
+
+## 시스템 아키텍처
+![system_architecture](https://github.com/Kernel360/E2E1-Orury/assets/44130863/22def7c2-e141-4592-a03d-3858e362dcc1)
+
+## ERD
+![ERD](https://github.com/Kernel360/E2E1-Orury/assets/44130863/af21f3c1-4bd2-4703-a765-5a1a3534e3d7)
+
+## 프로젝트 구조도
+> 📦orury
+┣ 📂batch
+┃ ┣ 📂job
+┃ ┃ ┗ 📜DeleteExpiredTokenJobConfig.java
+┃ ┗ 📂scheduler
+┃ ┃ ┗ 📜BatchScheduler.java
+┣ 📂config
+┃ ┣ 📂jwt
+┃ ┃ ┣ 📜CustomAuthenticationFailureHandler.java
+┃ ┃ ┣ 📜JwtAccessDeniedHandler.java
+┃ ┃ ┣ 📜JwtAuthenticationEntryPoint.java
+┃ ┃ ┣ 📜JwtFilter.java
+┃ ┃ ┣ 📜JwtSecurityConfig.java
+┃ ┃ ┗ 📜TokenProvider.java
+┃ ┣ 📜CorsConfig.java
+┃ ┣ 📜JasyptConfig.java
+┃ ┣ 📜SecurityConfig.java
+┃ ┗ 📜SwaggerConfig.java
+┣ 📂domain
+┃ ┣ 📂admin
+┃ ┃ ┣ 📂controller
+┃ ┃ ┃ ┣ 📜AdminBoardController.java
+┃ ┃ ┃ ┣ 📜AdminCommentController.java
+┃ ┃ ┃ ┣ 📜AdminPostController.java
+┃ ┃ ┃ ┗ 📜AdminUserController.java
+┃ ┃ ┗ 📂service
+┃ ┃ ┃ ┣ 📜AdminCommentService.java
+┃ ┃ ┃ ┣ 📜AdminPostService.java
+┃ ┃ ┃ ┗ 📜AdminUserService.java
+┃ ┣ 📂board
+┃ ┃ ┣ 📂controller
+┃ ┃ ┃ ┗ 📜BoardController.java
+┃ ┃ ┣ 📂db
+┃ ┃ ┃ ┣ 📜BoardEntity.java
+┃ ┃ ┃ ┗ 📜BoardRepository.java
+┃ ┃ ┣ 📂model
+┃ ┃ ┃ ┣ 📜BoardDto.java
+┃ ┃ ┃ ┗ 📜BoardRequest.java
+┃ ┃ ┗ 📂service
+┃ ┃ ┃ ┣ 📜BoardConverter.java
+┃ ┃ ┃ ┗ 📜BoardService.java
+┃ ┣ 📂comment
+┃ ┃ ┣ 📂controller
+┃ ┃ ┃ ┗ 📜CommentController.java
+┃ ┃ ┣ 📂db
+┃ ┃ ┃ ┣ 📜CommentEntity.java
+┃ ┃ ┃ ┣ 📜CommentLikeEntity.java
+┃ ┃ ┃ ┣ 📜CommentLikePK.java
+┃ ┃ ┃ ┣ 📜CommentLikeRepository.java
+┃ ┃ ┃ ┗ 📜CommentRepository.java
+┃ ┃ ┣ 📂model
+┃ ┃ ┃ ┣ 📜CommentDto.java
+┃ ┃ ┃ ┣ 📜CommentLikeDto.java
+┃ ┃ ┃ ┣ 📜CommentLikeRequest.java
+┃ ┃ ┃ ┗ 📜CommentRequest.java
+┃ ┃ ┗ 📂service
+┃ ┃ ┃ ┣ 📜CommentConverter.java
+┃ ┃ ┃ ┗ 📜CommentService.java
+┃ ┣ 📂config
+┃ ┣ 📂notification
+┃ ┃ ┣ 📂controller
+┃ ┃ ┃ ┗ 📜NotifyController.java
+┃ ┃ ┣ 📂db
+┃ ┃ ┃ ┗ 📜EmitterRepository.java
+┃ ┃ ┗ 📂service
+┃ ┃ ┃ ┗ 📜NotifyService.java
+┃ ┣ 📂post
+┃ ┃ ┣ 📂controller
+┃ ┃ ┃ ┗ 📜PostController.java
+┃ ┃ ┣ 📂db
+┃ ┃ ┃ ┣ 📜PostEntity.java
+┃ ┃ ┃ ┣ 📜PostLikeEntity.java
+┃ ┃ ┃ ┣ 📜PostLikePK.java
+┃ ┃ ┃ ┣ 📜PostLikeRepository.java
+┃ ┃ ┃ ┗ 📜PostRepository.java
+┃ ┃ ┣ 📂model
+┃ ┃ ┃ ┣ 📜PostDto.java
+┃ ┃ ┃ ┣ 📜PostLikeDto.java
+┃ ┃ ┃ ┣ 📜PostLikeRequest.java
+┃ ┃ ┃ ┗ 📜PostRequest.java
+┃ ┃ ┣ 📂repository
+┃ ┃ ┗ 📂service
+┃ ┃ ┃ ┣ 📜PostConverter.java
+┃ ┃ ┃ ┗ 📜PostService.java
+┃ ┗ 📂user
+┃ ┃ ┣ 📂controller
+┃ ┃ ┃ ┣ 📜AuthController.java
+┃ ┃ ┃ ┗ 📜UserController.java
+┃ ┃ ┣ 📂db
+┃ ┃ ┃ ┣ 📜AuthorityEntity.java
+┃ ┃ ┃ ┣ 📜AuthorityRepository.java
+┃ ┃ ┃ ┣ 📜RefreshTokenEntity.java
+┃ ┃ ┃ ┣ 📜RefreshTokenRepository.java
+┃ ┃ ┃ ┣ 📜UserEntity.java
+┃ ┃ ┃ ┗ 📜UserRepository.java
+┃ ┃ ┣ 📂model
+┃ ┃ ┃ ┣ 📜AuthorityDto.java
+┃ ┃ ┃ ┣ 📜LoginDto.java
+┃ ┃ ┃ ┣ 📜TokenDto.java
+┃ ┃ ┃ ┣ 📜UserDto.java
+┃ ┃ ┃ ┗ 📜UserResponseDto.java
+┃ ┃ ┗ 📂service
+┃ ┃ ┃ ┣ 📜CustomUserDetailsService.java
+┃ ┃ ┃ ┗ 📜UserService.java
+┣ 📂global
+┃ ┣ 📂common
+┃ ┃ ┣ 📜Api.java
+┃ ┃ ┣ 📜ApiResponse.java
+┃ ┃ ┣ 📜ApiStatus.java
+┃ ┃ ┣ 📜BaseEntity.java
+┃ ┃ ┣ 📜Listener.java
+┃ ┃ ┣ 📜Pagination.java
+┃ ┃ ┗ 📜SecurityUtil.java
+┃ ┣ 📂config
+┃ ┃ ┗ 📜JpaConfig.java
+┃ ┣ 📂constants
+┃ ┃ ┗ 📜Constant.java
+┃ ┣ 📂controller
+┃ ┣ 📂error
+┃ ┃ ┣ 📂code
+┃ ┃ ┃ ┣ 📜AuthorizationErrorCode.java
+┃ ┃ ┃ ┣ 📜BoardErrorCode.java
+┃ ┃ ┃ ┣ 📜CertificationErrorCode.java
+┃ ┃ ┃ ┣ 📜CommentErrorCode.java
+┃ ┃ ┃ ┣ 📜ErrorCode.java
+┃ ┃ ┃ ┣ 📜PostErrorCode.java
+┃ ┃ ┃ ┣ 📜ServerErrorCode.java
+┃ ┃ ┃ ┗ 📜UserErrorCode.java
+┃ ┃ ┣ 📂dto
+┃ ┃ ┃ ┗ 📜ErrorResponse.java
+┃ ┃ ┣ 📂exception
+┃ ┃ ┃ ┗ 📜BusinessException.java
+┃ ┃ ┗ 📜GlobalExceptionHandler.java
+┃ ┗ 📂message
+┃ ┃ ┣ 📂info
+┃ ┃ ┃ ┗ 📜InfoMessages.java
+┃ ┃ ┣ 📂success
+┃ ┃ ┗ 📂validation
+┗ 📜OruryApplication.java
## 사용법
### 1. apk를 다운받아서 사용하는 경우
diff --git a/backend/orury/.gitignore b/backend/orury/.gitignore
index d99209a..863e9a4 100644
--- a/backend/orury/.gitignore
+++ b/backend/orury/.gitignore
@@ -6,6 +6,7 @@ build/
!**/src/test/**/build/
LOCAL_LOG_URL_IS_UNDEFINED
.DS_Store
+AWS_LOG_URL_IS_UNDEFINED/
### STS ###
.apt_generated
diff --git a/backend/orury/build.gradle b/backend/orury/build.gradle
index 0689877..70fff87 100644
--- a/backend/orury/build.gradle
+++ b/backend/orury/build.gradle
@@ -47,6 +47,9 @@ dependencies {
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5'
implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.7.0'
+
+ implementation 'org.flywaydb:flyway-core'
+ implementation 'org.flywaydb:flyway-mysql'
}
tasks.named('test') {
diff --git a/backend/orury/src/main/java/com/kernel360/orury/config/SecurityConfig.java b/backend/orury/src/main/java/com/kernel360/orury/config/SecurityConfig.java
index 62671b3..1031152 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/config/SecurityConfig.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/config/SecurityConfig.java
@@ -1,17 +1,23 @@
package com.kernel360.orury.config;
import com.kernel360.orury.config.jwt.*;
+import com.kernel360.orury.config.jwt.admin.AdminJwtAuthenticationEntryPoint;
+import com.kernel360.orury.config.jwt.admin.AdminJwtFilter;
+import com.kernel360.orury.domain.user.db.UserRepository;
+import com.kernel360.orury.domain.user.service.CustomUserDetailsService;
import lombok.RequiredArgsConstructor;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.filter.CorsFilter;
@@ -35,20 +41,77 @@ public class SecurityConfig {
"/api/notify/**" // sse 테스트를 위해 임시로
);
private final TokenProvider tokenProvider;
+ private final UserRepository userRepository;
private final CorsFilter corsFilter;
private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
+ private final AdminJwtAuthenticationEntryPoint adminJwtAuthenticationEntryPoint;
private final JwtAccessDeniedHandler jwtAccessDeniedHandler;
- private CustomAuthenticationFailureHandler failureHandler;
+ private final CustomUserDetailsService customUserDetailsService;
+ @Value("${jwt.cookie-name}")
+ private String cookieName;
+ @Value("${jwt.refresh-cookie-name}")
+ private String cookieRefreshName;
+ @Value("${jwt.access-validity}")
+ private String accessCookieMaxAge;
+ @Value("${jwt.refresh-validity}")
+ private String refreshCookieMaxAge;
@Bean
- public PasswordEncoder passwordEncoder() {
+ public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
- public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+ public AuthenticationManager authenticationManager(
+ HttpSecurity http,
+ BCryptPasswordEncoder passwordEncoder
+ ) throws Exception {
+ return http.getSharedObject(AuthenticationManagerBuilder.class)
+ .userDetailsService(customUserDetailsService)
+ .passwordEncoder(passwordEncoder)
+ .and()
+ .build();
+ }
+
+ @Bean
+ @Order(1)
+ public SecurityFilterChain adminFilterChain(HttpSecurity http, AuthenticationManager authenticationManager) throws
+ Exception {
http
- // token을 사용하는 방식이기 때문에 csrf를 disable합니다.
+ .requestMatchers(requestMatchers -> requestMatchers
+ .antMatchers("/admin/**") // /api로 시작하는 요청을 처리
+ )
+ .csrf(csrf -> csrf.disable())
+
+ .addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
+ .exceptionHandling(exceptionHandling -> exceptionHandling
+ .accessDeniedHandler(jwtAccessDeniedHandler)
+ .authenticationEntryPoint(adminJwtAuthenticationEntryPoint)
+ )
+
+ .authorizeHttpRequests(authorizeHttpRequests -> authorizeHttpRequests
+ .mvcMatchers(SWAGGER.toArray(new String[0])).permitAll()
+ .antMatchers("/admin/login").permitAll()
+ .anyRequest().authenticated()
+ )
+
+ // 세션을 사용하지 않기 때문에 STATELESS로 설정
+ .sessionManagement(sessionManagement ->
+ sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+ )
+ // JWT필터 적용
+ .addFilterBefore(new AdminJwtFilter(tokenProvider, cookieName, cookieRefreshName, accessCookieMaxAge,
+ refreshCookieMaxAge), UsernamePasswordAuthenticationFilter.class);
+ return http.build();
+ }
+
+ @Bean
+ @Order(2)
+ public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {
+ http
+ .requestMatchers(requestMatchers -> requestMatchers
+ .antMatchers("/api/**") // /api로 시작하는 요청을 처리
+ )
.csrf(csrf -> csrf.disable())
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
diff --git a/backend/orury/src/main/java/com/kernel360/orury/config/jwt/CustomAuthenticationFailureHandler.java b/backend/orury/src/main/java/com/kernel360/orury/config/jwt/CustomAuthenticationFailureHandler.java
index 45213fe..3d6342f 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/config/jwt/CustomAuthenticationFailureHandler.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/config/jwt/CustomAuthenticationFailureHandler.java
@@ -2,7 +2,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kernel360.orury.global.common.ApiResponse;
-import com.kernel360.orury.global.message.errors.ErrorMessages;
+import com.kernel360.orury.global.error.code.CertificationErrorCode;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
@@ -20,7 +20,7 @@ public void onAuthenticationFailure(HttpServletRequest request, HttpServletRespo
// 여기에 원하는 JSON 응답을 작성합니다.
// 예시로는 ApiResponse를 사용했습니다.
- ApiResponse apiResponse = ApiResponse.error(HttpStatus.UNAUTHORIZED, 401, ErrorMessages.EXPIRED_JWT.getMessage());
+ ApiResponse apiResponse = ApiResponse.error(HttpStatus.UNAUTHORIZED, 401, CertificationErrorCode.EXPIRED_ACCESS_JWT.getMessage());
new ObjectMapper().writeValue(response.getWriter(), apiResponse);
}
}
\ No newline at end of file
diff --git a/backend/orury/src/main/java/com/kernel360/orury/config/jwt/JwtAuthenticationEntryPoint.java b/backend/orury/src/main/java/com/kernel360/orury/config/jwt/JwtAuthenticationEntryPoint.java
index 5c43cb4..e0baa9b 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/config/jwt/JwtAuthenticationEntryPoint.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/config/jwt/JwtAuthenticationEntryPoint.java
@@ -24,7 +24,15 @@ public void commence(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException
) {
- resolver.resolveException(request, response, null, (Exception) request.getAttribute("exception"));
+ // JwtFilter에서 처리한 밣생한 예외를 받는 부분
+ if(request.getAttribute("exception") != null) {
+ resolver.resolveException(request, response, null, (Exception) request.getAttribute("exception"));
+ }
+
+ // jwt token에서 정의한 에러 외 filter에서 발생한 예외를 global handler로 보냄
+ else {
+ resolver.resolveException(request, response, null, authException);
+ }
// 유효한 자격증명을 제공하지 않고 접근하려 할때 401
// response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/config/jwt/JwtFilter.java b/backend/orury/src/main/java/com/kernel360/orury/config/jwt/JwtFilter.java
index 8b1d21e..3dc9e4b 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/config/jwt/JwtFilter.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/config/jwt/JwtFilter.java
@@ -3,26 +3,23 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kernel360.orury.global.constants.Constant;
-import com.kernel360.orury.global.exception.RefreshExpiredJwtException;
-import com.kernel360.orury.global.message.errors.ErrorMessages;
+import com.kernel360.orury.global.error.code.CertificationErrorCode;
+import com.kernel360.orury.global.error.exception.BusinessException;
import io.jsonwebtoken.ExpiredJwtException;
+import io.jsonwebtoken.MalformedJwtException;
+import io.jsonwebtoken.security.SignatureException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
-import org.springframework.web.filter.GenericFilterBean;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
-
import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-
import java.io.IOException;
public class JwtFilter extends OncePerRequestFilter {
@@ -64,58 +61,39 @@ public void doFilterInternal(HttpServletRequest servletRequest, HttpServletRespo
SecurityContextHolder.getContext().setAuthentication(authentication);
logger.debug("Security Context에 '{}' 인증 정보를 저장했습니다, uri: {}", authentication.getName(), servletRequest.getRequestURI());
}catch(ExpiredJwtException e){
- RefreshExpiredJwtException refreshExpiredJwtException = new RefreshExpiredJwtException("Refresh Expired Jwt Exception");
+ BusinessException refreshExpiredJwtException = new BusinessException(CertificationErrorCode.EXPIRED_REFRESH_JWT);
servletRequest.setAttribute("exception", refreshExpiredJwtException);
+ }catch(SignatureException e) {
+ BusinessException signatureException = new BusinessException(CertificationErrorCode.ILLEGAL_ARGUMENT_JWT);
+ servletRequest.setAttribute("exception", signatureException);
+ }catch (MalformedJwtException e){
+ BusinessException newException = new BusinessException(CertificationErrorCode.MALFORMED_JWT);
+ servletRequest.setAttribute("exception", newException);
}catch(Exception e){
servletRequest.setAttribute("exception", e);
}
-// } catch (ExpiredJwtException e) {
-// // Create an ObjectMapper
-// ObjectMapper objectMapper = new ObjectMapper();
-// // Create a JSON object
-// JsonNode errorJson = objectMapper.createObjectNode()
-// .put("error", ErrorMessages.EXPIRED_REFRESH_JWT.getMessage())
-// .put("errorCode", 402);
-// // Convert JSON object to string
-// tempResponse(objectMapper, errorJson, servletResponse);
-// return;
-// }
}else {
try {
tokenProvider.validateToken(accessToken);
Authentication authentication = tokenProvider.getAuthentication(accessToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
logger.debug("Security Context에 '{}' 인증 정보를 저장했습니다, uri: {}", authentication.getName(), servletRequest.getRequestURI());
+ }catch(ExpiredJwtException e) {
+ BusinessException accessExpiredJwtException = new BusinessException(CertificationErrorCode.EXPIRED_ACCESS_JWT);
+ servletRequest.setAttribute("exception", accessExpiredJwtException);
+ }catch(SignatureException e) {
+ BusinessException signatureException = new BusinessException(CertificationErrorCode.ILLEGAL_ARGUMENT_JWT);
+ servletRequest.setAttribute("exception", signatureException);
+ }catch (MalformedJwtException e){
+ BusinessException newException = new BusinessException(CertificationErrorCode.MALFORMED_JWT);
+ servletRequest.setAttribute("exception", newException);
}catch(Exception e){
servletRequest.setAttribute("exception", e);
}
-// } catch (Exception e) {
-// // Create an ObjectMapper
-// ObjectMapper objectMapper = new ObjectMapper();
-// // Create a JSON object
-// JsonNode errorJson = objectMapper.createObjectNode()
-// .put("error", ErrorMessages.EXPIRED_JWT.getMessage())
-// .put("errorCode", 401);
-// // Convert JSON object to string
-// tempResponse(objectMapper, errorJson, servletResponse);
-// return;
-// }
}
-
filterChain.doFilter(servletRequest, servletResponse);
}
- private static void tempResponse(ObjectMapper objectMapper, JsonNode errorJson, HttpServletResponse httpServletResponse) throws IOException {
- String jsonString = objectMapper.writeValueAsString(errorJson);
- // Set status code and headers
- httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
- httpServletResponse.setContentType("application/json; charset=UTF-8");
- httpServletResponse.setCharacterEncoding("UTF-8");
- // Write JSON string to the response body
- httpServletResponse.getWriter().write(jsonString);
- httpServletResponse.getWriter().flush();
- }
-
//리퀘스트 헤더에서 토큰 정보를 꺼내온다
private String resolveToken(String authorizationHeader) {
if(StringUtils.hasText(authorizationHeader)) {
diff --git a/backend/orury/src/main/java/com/kernel360/orury/config/jwt/TokenProvider.java b/backend/orury/src/main/java/com/kernel360/orury/config/jwt/TokenProvider.java
index d89b847..8ad3add 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/config/jwt/TokenProvider.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/config/jwt/TokenProvider.java
@@ -8,10 +8,14 @@
import com.kernel360.orury.domain.user.db.UserEntity;
import com.kernel360.orury.domain.user.db.UserRepository;
import com.kernel360.orury.global.constants.Constant;
-import com.kernel360.orury.global.exception.TokenExpiredException;
-import com.kernel360.orury.global.exception.TokenNotFoundException;
-import com.kernel360.orury.global.message.errors.ErrorMessages;
-import io.jsonwebtoken.*;
+import com.kernel360.orury.global.error.code.CertificationErrorCode;
+import com.kernel360.orury.global.error.code.UserErrorCode;
+import com.kernel360.orury.global.error.exception.BusinessException;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.ExpiredJwtException;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
@@ -54,7 +58,7 @@ public TokenProvider(
@Value("${jwt.secret}") String secret,
UserRepository userRepository,
RefreshTokenRepository tokenRepository
- ) {
+ ) {
this.refreshValidityMs = refershValiditySec * 1000L;
this.accessValidityMs = accessValiditySec * 1000L;
this.secret = secret;
@@ -69,52 +73,51 @@ public void afterPropertiesSet() {
this.key = Keys.hmacShaKeyFor(keyBytes);
}
-
-
- public String createAccessToken(Authentication authentication){
+ public String createAccessToken(Authentication authentication) {
String authorities = authentication.getAuthorities().stream()
- .map(GrantedAuthority::getAuthority)
- .collect(Collectors.joining(","));
+ .map(GrantedAuthority::getAuthority)
+ .collect(Collectors.joining(","));
long now = (new Date()).getTime();
Date validity = new Date(now + accessValidityMs);
UserEntity user = userRepository.findByEmailAddr(authentication.getName()).orElseThrow(
- ()-> new RuntimeException(ErrorMessages.THERE_IS_NO_USER.getMessage())
+ () -> new RuntimeException(UserErrorCode.THERE_IS_NO_USER.getMessage())
);
return Jwts.builder()
- .claim(Constant.USERID.getMessage(), user.getId())
- .setSubject(authentication.getName())
- .claim(AUTHORITIES_KEY, authorities)
- .signWith(key, SignatureAlgorithm.HS512)
- .setExpiration(validity)
- .compact();
+ .claim(Constant.USERID.getMessage(), user.getId())
+ .setSubject(authentication.getName())
+ .claim(AUTHORITIES_KEY, authorities)
+ .signWith(key, SignatureAlgorithm.HS512)
+ .setExpiration(validity)
+ .compact();
}
- public String createRefreshToken(Authentication authentication){
+
+ public String createRefreshToken(Authentication authentication) {
long now = (new Date()).getTime();
Date validity = new Date(now + this.refreshValidityMs);
//
var userId = userRepository.findByEmailAddr(authentication.getName()).orElseThrow(
- ()-> new RuntimeException(ErrorMessages.THERE_IS_NO_USER.getMessage())
+ () -> new BusinessException(UserErrorCode.THERE_IS_NO_USER)
).getId();
return Jwts.builder()
- .claim( Constant.USERID.getMessage(), userId)
- .signWith(key, SignatureAlgorithm.HS512)
- .setExpiration(validity)
- .compact();
+ .claim(Constant.USERID.getMessage(), userId)
+ .signWith(key, SignatureAlgorithm.HS512)
+ .setExpiration(validity)
+ .compact();
}
// 토큰을 파라미터로 받아서 클레임을 만들고 이를 이용해 유저 객체를 만들고 Authentication 객체 리턴
public Authentication getAuthentication(String token) throws JsonProcessingException {
-// Claims claims = Jwts
-// .parserBuilder()
-// .setSigningKey(key)
-// .build()
-// .parseClaimsJws(token)
-// .getBody();
-
+ // Claims claims = Jwts
+ // .parserBuilder()
+ // .setSigningKey(key)
+ // .build()
+ // .parseClaimsJws(token)
+ // .getBody();
+
String[] chunks = token.split("\\.");
String payload = new String(Base64.getUrlDecoder().decode(chunks[1]));
@@ -123,7 +126,7 @@ public Authentication getAuthentication(String token) throws JsonProcessingExcep
JsonNode jsonNode = objectMapper.readTree(payload);
// 필요한 정보 추출
-// String userId = jsonNode.get("userId").asText();
+ // String userId = jsonNode.get("userId").asText();
String sub = jsonNode.get("sub").asText();
String auth = jsonNode.get("auth").asText();
@@ -137,52 +140,60 @@ public Authentication getAuthentication(String token) throws JsonProcessingExcep
return new UsernamePasswordAuthenticationToken(principal, token, authorities);
}
-
- public boolean validateToken(String token ) throws ExpiredJwtException{
+ public boolean validateToken(String token) throws ExpiredJwtException {
Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token);
return true;
}
- public void storeToken(String token){
+ public void storeToken(String token) {
Claims claims = Jwts
- .parserBuilder()
- .setSigningKey(key)
- .build()
- .parseClaimsJws(token)
- .getBody();
+ .parserBuilder()
+ .setSigningKey(key)
+ .build()
+ .parseClaimsJws(token)
+ .getBody();
var userId = Long.parseLong(claims.get("userId").toString());
var user = userRepository.findById(userId).orElseThrow(
- () -> new RuntimeException(ErrorMessages.THERE_IS_NO_USER.getMessage())
+ () -> new BusinessException(UserErrorCode.THERE_IS_NO_USER)
);
RefreshTokenEntity existingToken = refreshTokenRepository.findByUserId(userId).orElse(null);
- if(existingToken != null){
+ if (existingToken != null) {
refreshTokenRepository.delete(existingToken);
}
var expiredDate = claims.getExpiration().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
var refreshTokenEntity = RefreshTokenEntity.builder()
- .tokenValue(token)
- .user(user)
- .expirationDate(expiredDate)
- .build();
+ .tokenValue(token)
+ .user(user)
+ .expirationDate(expiredDate)
+ .build();
refreshTokenRepository.save(refreshTokenEntity);
}
public boolean validateRefreshToken(String refreshToken) {
var refreshTokenEntity = refreshTokenRepository.findByTokenValue(refreshToken).orElseThrow(
- () -> new TokenNotFoundException(ErrorMessages.ILLEGAL_REFRESH_JWT.getMessage())
+ () -> new BusinessException(CertificationErrorCode.ILLEGAL_REFRESH_JWT)
);
var expireDate = refreshTokenEntity.getExpirationDate();
if (LocalDateTime.now().isAfter(expireDate)) {
- throw new TokenExpiredException(ErrorMessages.EXPIRED_REFRESH_JWT.getMessage());
+ throw new BusinessException(CertificationErrorCode.EXPIRED_REFRESH_JWT);
}
return validateToken(refreshToken);
}
+ public boolean isTokenExpired(String token) {
+ Date expirationDate = Jwts.parserBuilder()
+ .setSigningKey(key)
+ .build()
+ .parseClaimsJws(token)
+ .getBody()
+ .getExpiration();
+ return expirationDate.before(new Date());
+ }
}
\ No newline at end of file
diff --git a/backend/orury/src/main/java/com/kernel360/orury/config/jwt/admin/AdminJwtAuthenticationEntryPoint.java b/backend/orury/src/main/java/com/kernel360/orury/config/jwt/admin/AdminJwtAuthenticationEntryPoint.java
new file mode 100644
index 0000000..6ebb636
--- /dev/null
+++ b/backend/orury/src/main/java/com/kernel360/orury/config/jwt/admin/AdminJwtAuthenticationEntryPoint.java
@@ -0,0 +1,21 @@
+package com.kernel360.orury.config.jwt.admin;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AdminJwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
+ @Override
+ public void commence(HttpServletRequest request,
+ HttpServletResponse response,
+ AuthenticationException authException) throws IOException {
+ // 유효한 자격증명을 제공하지 않고 접근하려 할때 redirect
+ response.sendRedirect("/admin/login");
+ }
+}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/config/jwt/admin/AdminJwtFilter.java b/backend/orury/src/main/java/com/kernel360/orury/config/jwt/admin/AdminJwtFilter.java
new file mode 100644
index 0000000..55f4b63
--- /dev/null
+++ b/backend/orury/src/main/java/com/kernel360/orury/config/jwt/admin/AdminJwtFilter.java
@@ -0,0 +1,92 @@
+package com.kernel360.orury.config.jwt.admin;
+
+import java.io.IOException;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import com.kernel360.orury.config.jwt.TokenProvider;
+
+import io.jsonwebtoken.ExpiredJwtException;
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor
+public class AdminJwtFilter extends OncePerRequestFilter {
+
+ private final TokenProvider tokenProvider;
+ private final String cookieName;
+ private final String cookieRefreshName;
+ private final String accessCookieMaxAge;
+ private final String refreshCookieMaxAge;
+
+ //토큰의 인증정보를 SecurityContext에 저장
+ @Override
+ public void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
+ FilterChain filterChain) throws
+ IOException,
+ ServletException {
+ try {
+ String accessToken = resolveToken(request, cookieName);
+ tokenProvider.validateToken(accessToken);
+ Authentication authentication = tokenProvider.getAuthentication(accessToken);
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ } catch (ExpiredJwtException e) {
+ try {
+ String accessToken = resolveToken(request, cookieName);
+ String refreshToken = resolveToken(request, cookieRefreshName);
+ tokenProvider.validateToken(refreshToken);
+ Authentication authentication = tokenProvider.getAuthentication(accessToken);
+ String newAccessToken = tokenProvider.createAccessToken(authentication);
+ Cookie accessTokenCookie = new Cookie(cookieName, newAccessToken);
+
+ accessTokenCookie.setHttpOnly(true);
+ accessTokenCookie.setMaxAge(60 * 60 * 24);
+ accessTokenCookie.setPath("/");
+
+ response.addCookie(accessTokenCookie);
+
+ Authentication newAuthentication = tokenProvider.getAuthentication(newAccessToken);
+ SecurityContextHolder.getContext().setAuthentication(newAuthentication);
+ } catch (ExpiredJwtException ex) {
+ clearAuthenticationAndCookie(response);
+ }
+ } catch (IllegalArgumentException ignored) {
+ }
+ filterChain.doFilter(request, response);
+ }
+
+ //리퀘스트 헤더에서 토큰 정보를 꺼내온다
+ private String resolveToken(HttpServletRequest request, String cookieName) {
+ Cookie[] cookies = request.getCookies();
+ if (cookies != null) {
+ for (Cookie cookie : cookies) {
+ if (cookieName.equals(cookie.getName())) { // 쿠키 이름에 따라서 변경
+ return cookie.getValue();
+ }
+ }
+ }
+ return null;
+ }
+
+ private void clearAuthenticationAndCookie(HttpServletResponse response) {
+ SecurityContextHolder.clearContext();
+ Cookie accessCookie = new Cookie(cookieName, null);
+ accessCookie.setPath("/");
+ accessCookie.setHttpOnly(true);
+ accessCookie.setMaxAge(0);
+ response.addCookie(accessCookie);
+ Cookie refreshCookie = new Cookie(cookieRefreshName, null);
+ refreshCookie.setPath("/");
+ refreshCookie.setHttpOnly(true);
+ refreshCookie.setMaxAge(0);
+ response.addCookie(refreshCookie);
+ }
+}
+
diff --git a/backend/orury/src/main/java/com/kernel360/orury/domain/admin/controller/AdminAuthController.java b/backend/orury/src/main/java/com/kernel360/orury/domain/admin/controller/AdminAuthController.java
new file mode 100644
index 0000000..152ea1d
--- /dev/null
+++ b/backend/orury/src/main/java/com/kernel360/orury/domain/admin/controller/AdminAuthController.java
@@ -0,0 +1,91 @@
+package com.kernel360.orury.domain.admin.controller;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import com.kernel360.orury.config.jwt.TokenProvider;
+
+@Controller
+@RequestMapping("/admin")
+public class AdminAuthController {
+ private final TokenProvider tokenProvider;
+ private final AuthenticationManagerBuilder authenticationManagerBuilder;
+ @Value("${jwt.cookie-name}")
+ private String cookieName;
+ @Value("${jwt.refresh-cookie-name}")
+ private String cookieRefreshName;
+ @Value("${jwt.access-validity}")
+ private String accessCookieMaxAge;
+ @Value("${jwt.refresh-validity}")
+ private String refreshCookieMaxAge;
+
+ public AdminAuthController(TokenProvider tokenProvider, AuthenticationManagerBuilder authenticationManagerBuilder) {
+ this.tokenProvider = tokenProvider;
+ this.authenticationManagerBuilder = authenticationManagerBuilder;
+ }
+
+ @GetMapping("/login")
+ public String login() {
+ return "pages-login";
+ }
+
+ @PostMapping("/login")
+ public String authenticate(@Valid @RequestParam String emailAddr, String password,
+ HttpServletResponse response) {
+
+ UsernamePasswordAuthenticationToken authenticationToken =
+ new UsernamePasswordAuthenticationToken(emailAddr, password);
+
+ Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+
+ String accessToken = tokenProvider.createAccessToken(authentication);
+ String refreshToken = tokenProvider.createRefreshToken(authentication);
+ tokenProvider.storeToken(refreshToken);
+
+ Cookie accessTokenCookie = new Cookie(cookieName, accessToken);
+ Cookie refreshTokenCookie = new Cookie(cookieRefreshName, refreshToken);
+
+ accessTokenCookie.setHttpOnly(true);
+ accessTokenCookie.setMaxAge(Integer.parseInt(accessCookieMaxAge) * 1000);
+ accessTokenCookie.setPath("/");
+ refreshTokenCookie.setHttpOnly(true);
+ refreshTokenCookie.setMaxAge(Integer.parseInt(refreshCookieMaxAge));
+ refreshTokenCookie.setPath("/");
+
+ response.addCookie(accessTokenCookie);
+ response.addCookie(refreshTokenCookie);
+
+ return "redirect:/admin/board";
+ }
+
+ @PostMapping("/logout")
+ public String logout(HttpServletResponse response) {
+ SecurityContextHolder.clearContext();
+ Cookie accessCookie = new Cookie(cookieName, null);
+ accessCookie.setPath("/");
+ accessCookie.setHttpOnly(true);
+ accessCookie.setMaxAge(0);
+ response.addCookie(accessCookie);
+ Cookie refreshCookie = new Cookie(cookieRefreshName, null);
+ refreshCookie.setPath("/");
+ refreshCookie.setHttpOnly(true);
+ refreshCookie.setMaxAge(0);
+ response.addCookie(refreshCookie);
+
+ return "redirect:/admin/login";
+ }
+}
+
diff --git a/backend/orury/src/main/java/com/kernel360/orury/domain/admin/controller/AdminBoardController.java b/backend/orury/src/main/java/com/kernel360/orury/domain/admin/controller/AdminBoardController.java
index c7070a7..c35a5a5 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/domain/admin/controller/AdminBoardController.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/domain/admin/controller/AdminBoardController.java
@@ -25,11 +25,6 @@ public class AdminBoardController {
private final BoardService boardService;
- @GetMapping
- public String index() {
- return "index";
- }
-
@GetMapping("/board")
public String board(Model model) {
List boardList = boardService.getBoardList();
diff --git a/backend/orury/src/main/java/com/kernel360/orury/domain/admin/controller/AdminPostController.java b/backend/orury/src/main/java/com/kernel360/orury/domain/admin/controller/AdminPostController.java
index 6063c50..a9c0c7c 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/domain/admin/controller/AdminPostController.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/domain/admin/controller/AdminPostController.java
@@ -2,24 +2,17 @@
import java.util.List;
-import javax.validation.Valid;
-
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.kernel360.orury.domain.admin.service.AdminPostService;
-import com.kernel360.orury.domain.board.model.BoardDto;
-import com.kernel360.orury.domain.board.model.BoardRequest;
-import com.kernel360.orury.domain.board.service.BoardService;
import com.kernel360.orury.domain.post.model.PostDto;
import com.kernel360.orury.domain.post.model.PostRequest;
-import com.kernel360.orury.domain.post.service.PostService;
import lombok.RequiredArgsConstructor;
diff --git a/backend/orury/src/main/java/com/kernel360/orury/domain/admin/controller/AdminUserController.java b/backend/orury/src/main/java/com/kernel360/orury/domain/admin/controller/AdminUserController.java
index 99cf1f9..5977aaa 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/domain/admin/controller/AdminUserController.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/domain/admin/controller/AdminUserController.java
@@ -1,21 +1,17 @@
package com.kernel360.orury.domain.admin.controller;
-import java.awt.image.BufferStrategy;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.kernel360.orury.domain.admin.service.AdminUserService;
-import com.kernel360.orury.domain.user.db.UserRepository;
import com.kernel360.orury.domain.user.model.UserDto;
-import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Controller
diff --git a/backend/orury/src/main/java/com/kernel360/orury/domain/admin/service/AdminCommentService.java b/backend/orury/src/main/java/com/kernel360/orury/domain/admin/service/AdminCommentService.java
index eb3abb6..7afdcf5 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/domain/admin/service/AdminCommentService.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/domain/admin/service/AdminCommentService.java
@@ -1,13 +1,5 @@
package com.kernel360.orury.domain.admin.service;
-import java.time.LocalDateTime;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import javax.servlet.http.PushBuilder;
-
-import org.springframework.stereotype.Service;
-
import com.kernel360.orury.domain.comment.db.CommentEntity;
import com.kernel360.orury.domain.comment.db.CommentRepository;
import com.kernel360.orury.domain.comment.model.CommentDto;
@@ -17,9 +9,13 @@
import com.kernel360.orury.domain.post.db.PostRepository;
import com.kernel360.orury.domain.user.db.UserRepository;
import com.kernel360.orury.global.constants.Constant;
-import com.kernel360.orury.global.message.errors.ErrorMessages;
-
+import com.kernel360.orury.global.error.code.PostErrorCode;
+import com.kernel360.orury.global.error.exception.BusinessException;
import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.List;
@Service
@RequiredArgsConstructor
@@ -32,7 +28,8 @@ public class AdminCommentService {
public CommentDto createComment(CommentRequest commentRequest) {
PostEntity postEntity = postRepository.findById(commentRequest.getPostId())
.orElseThrow(
- () -> new RuntimeException(ErrorMessages.THERE_IS_NO_POST.getMessage() + commentRequest.getPostId()));
+ () -> new BusinessException(PostErrorCode.THERE_IS_NO_POST)
+ );
CommentEntity commentEntity = CommentEntity.builder()
.userId(commentRequest.getUserId())
diff --git a/backend/orury/src/main/java/com/kernel360/orury/domain/admin/service/AdminPostService.java b/backend/orury/src/main/java/com/kernel360/orury/domain/admin/service/AdminPostService.java
index 95bd13d..6b51d01 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/domain/admin/service/AdminPostService.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/domain/admin/service/AdminPostService.java
@@ -1,12 +1,5 @@
package com.kernel360.orury.domain.admin.service;
-import java.time.LocalDateTime;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Optional;
-
-import org.springframework.stereotype.Service;
-
import com.kernel360.orury.domain.board.db.BoardRepository;
import com.kernel360.orury.domain.post.db.PostEntity;
import com.kernel360.orury.domain.post.db.PostRepository;
@@ -15,9 +8,15 @@
import com.kernel360.orury.domain.post.service.PostConverter;
import com.kernel360.orury.domain.user.db.UserRepository;
import com.kernel360.orury.global.constants.Constant;
-import com.kernel360.orury.global.message.errors.ErrorMessages;
-
+import com.kernel360.orury.global.error.code.BoardErrorCode;
+import com.kernel360.orury.global.error.code.PostErrorCode;
+import com.kernel360.orury.global.error.exception.BusinessException;
import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Optional;
@RequiredArgsConstructor
@Service
@@ -32,15 +31,13 @@ public PostDto createPost(
PostRequest postRequest
) {
var boardEntity = boardRepository.findById(postRequest.getBoardId())
- .orElseThrow(() -> new RuntimeException(ErrorMessages.THERE_IS_NO_BOARD.getMessage()));
+ .orElseThrow(() -> new BusinessException(BoardErrorCode.THERE_IS_NO_BOARD));
var entity = PostEntity.builder()
.postTitle(postRequest.getPostTitle())
.postContent(postRequest.getPostContent())
.userId(1L)
.board(boardEntity)
- // .thumbnailUrl(postRequest.getPostImageList().isEmpty() ? null : postRequest.getPostImageList().get(0))
- // .images(postRequest.getPostImageList().isEmpty() ? null : String.join(",", postRequest.getPostImageList()))
.createdBy(Constant.ADMIN.getMessage())
.createdAt(LocalDateTime.now())
.updatedBy(Constant.ADMIN.getMessage())
@@ -54,7 +51,7 @@ public PostDto createPost(
public PostDto getPost(Long id) {
Optional postEntityOptional = postRepository.findById(id);
PostEntity post = postEntityOptional.orElseThrow(
- () -> new RuntimeException(ErrorMessages.THERE_IS_NO_POST.getMessage() + id));
+ () -> new BusinessException(PostErrorCode.THERE_IS_NO_POST));
return postConverter.toDto(post);
}
@@ -64,7 +61,7 @@ public PostDto updatePost(
Long postId = postRequest.getId();
var postEntityOptional = postRepository.findById(postId);
var entity = postEntityOptional.orElseThrow(
- () -> new RuntimeException(ErrorMessages.THERE_IS_NO_POST.getMessage() + postId));
+ () -> new BusinessException(PostErrorCode.THERE_IS_NO_POST));
var dto = postConverter.toDto(entity);
dto.setPostTitle(postRequest.getPostTitle());
dto.setPostContent(postRequest.getPostContent());
diff --git a/backend/orury/src/main/java/com/kernel360/orury/domain/admin/service/AdminUserService.java b/backend/orury/src/main/java/com/kernel360/orury/domain/admin/service/AdminUserService.java
index 27191a3..46cb06f 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/domain/admin/service/AdminUserService.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/domain/admin/service/AdminUserService.java
@@ -11,7 +11,6 @@
import com.kernel360.orury.domain.user.db.UserEntity;
import com.kernel360.orury.domain.user.db.UserRepository;
import com.kernel360.orury.domain.user.model.UserDto;
-import com.kernel360.orury.global.exception.NotFoundMemberException;
import lombok.RequiredArgsConstructor;
diff --git a/backend/orury/src/main/java/com/kernel360/orury/domain/board/service/BoardService.java b/backend/orury/src/main/java/com/kernel360/orury/domain/board/service/BoardService.java
index 8c025a5..5920c44 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/domain/board/service/BoardService.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/domain/board/service/BoardService.java
@@ -4,12 +4,12 @@
import com.kernel360.orury.domain.board.db.BoardRepository;
import com.kernel360.orury.domain.board.model.BoardDto;
import com.kernel360.orury.domain.board.model.BoardRequest;
-import com.kernel360.orury.domain.post.db.PostEntity;
import com.kernel360.orury.domain.post.db.PostRepository;
import com.kernel360.orury.domain.post.model.PostDto;
import com.kernel360.orury.domain.post.service.PostConverter;
import com.kernel360.orury.global.constants.Constant;
-import com.kernel360.orury.global.message.errors.ErrorMessages;
+import com.kernel360.orury.global.error.code.BoardErrorCode;
+import com.kernel360.orury.global.error.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -54,7 +54,7 @@ public BoardDto updateBoard(
BoardRequest boardRequest
) {
BoardEntity entity = boardRepository.findById(boardRequest.getId())
- .orElseThrow(() -> new RuntimeException(ErrorMessages.THERE_IS_NO_BOARD.getMessage() + boardRequest.getId()));
+ .orElseThrow(() -> new BusinessException(BoardErrorCode.THERE_IS_NO_BOARD));
BoardDto updatedDto = boardConverter.toDto(entity);
updatedDto.setBoardTitle(boardRequest.getBoardTitle());
@@ -72,7 +72,7 @@ public void deleteBoard(Long id) {
public BoardDto getBoard(Long id) {
var entity = boardRepository.findById(id)
- .orElseThrow(() -> new RuntimeException(ErrorMessages.THERE_IS_NO_BOARD.getMessage() + id));
+ .orElseThrow(() -> new BusinessException(BoardErrorCode.THERE_IS_NO_BOARD));
return boardConverter.toDto(entity);
}
@@ -80,7 +80,7 @@ public BoardDto getBoard(Long id) {
public List getNoticeBoard(Long id) {
var noticeList = postRepository.findAllByBoardId(id);
if(noticeList.isEmpty()) {
- new RuntimeException(ErrorMessages.THERE_IS_NO_BOARD.getMessage() + id);
+ throw new BusinessException(BoardErrorCode.THERE_IS_NO_BOARD);
}
return noticeList.stream()
diff --git a/backend/orury/src/main/java/com/kernel360/orury/domain/comment/controller/CommentController.java b/backend/orury/src/main/java/com/kernel360/orury/domain/comment/controller/CommentController.java
index 8fd046f..f519ae4 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/domain/comment/controller/CommentController.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/domain/comment/controller/CommentController.java
@@ -5,10 +5,8 @@
import com.kernel360.orury.domain.comment.model.CommentLikeRequest;
import com.kernel360.orury.domain.comment.model.CommentRequest;
import com.kernel360.orury.domain.comment.service.CommentService;
-import com.kernel360.orury.domain.post.model.PostLikeRequest;
-import com.kernel360.orury.global.common.ApiResponse;
import com.kernel360.orury.global.constants.Constant;
-import com.kernel360.orury.global.message.errors.ErrorMessages;
+import com.kernel360.orury.global.error.code.AuthorizationErrorCode;
import com.kernel360.orury.global.message.info.InfoMessages;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
@@ -54,7 +52,7 @@ public ResponseEntity updateComment(
commentService.updateComment(commentRequest);
return ResponseEntity.ok(InfoMessages.COMMENT_UPDATED.getMessage());
} else
- return ResponseEntity.status(HttpStatus.FORBIDDEN).body(ErrorMessages.THERE_IS_NO_AUTHORITY.getMessage());
+ return ResponseEntity.status(HttpStatus.FORBIDDEN).body(AuthorizationErrorCode.THERE_IS_NO_AUTHORITY.getMessage());
}
// 댓글 삭제
@@ -74,7 +72,7 @@ public ResponseEntity deleteComment(
return ResponseEntity.ok(InfoMessages.COMMENT_DELETED.getMessage());
}else{
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(
- "댓글 삭제" + ErrorMessages.THERE_IS_NO_AUTHORITY.getMessage());
+ "댓글 삭제" + AuthorizationErrorCode.THERE_IS_NO_AUTHORITY.getMessage());
}
}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/domain/comment/service/CommentConverter.java b/backend/orury/src/main/java/com/kernel360/orury/domain/comment/service/CommentConverter.java
index 3fc16c0..2cf9693 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/domain/comment/service/CommentConverter.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/domain/comment/service/CommentConverter.java
@@ -9,17 +9,14 @@
import com.kernel360.orury.domain.post.db.PostRepository;
import com.kernel360.orury.domain.user.db.UserEntity;
import com.kernel360.orury.domain.user.db.UserRepository;
-import com.kernel360.orury.global.message.errors.ErrorMessages;
+import com.kernel360.orury.global.error.code.PostErrorCode;
+import com.kernel360.orury.global.error.code.UserErrorCode;
+import com.kernel360.orury.global.error.exception.BusinessException;
import lombok.RequiredArgsConstructor;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
@Service
@RequiredArgsConstructor
public class CommentConverter {
@@ -33,7 +30,7 @@ public CommentDto toDto(CommentEntity commentEntity) {
try {
// 유저 닉네임 할당
UserEntity userEntity = userRepository.findById(commentEntity.getUserId())
- .orElseThrow(() -> new RuntimeException(ErrorMessages.THERE_IS_NO_USER.getMessage() + commentEntity.getUserId()));
+ .orElseThrow(() -> new BusinessException(UserErrorCode.THERE_IS_NO_USER));
// 로그인 유저 좋아요 여부 판단
long loginId = getLoginId();
@@ -57,8 +54,7 @@ public CommentDto toDto(CommentEntity commentEntity) {
.build();
} catch (Exception e) {
// 예외가 발생한 경우 JSON 형식의 응답을 생성
- String errorMessage = ErrorMessages.THERE_IS_NO_USER.getMessage();
- throw new RuntimeException(errorMessage);
+ throw new BusinessException(UserErrorCode.THERE_IS_NO_USER);
}
}
@@ -66,7 +62,7 @@ public CommentDto toDto(CommentEntity commentEntity) {
public CommentEntity toEntity(CommentDto commentdto) {
PostEntity postEntity = postRepository.findById(commentdto.getPostId())
.orElseThrow(
- () -> new RuntimeException(ErrorMessages.THERE_IS_NO_POST.getMessage() + commentdto.getPostId())
+ () -> new BusinessException(PostErrorCode.THERE_IS_NO_POST)
);
return CommentEntity.builder()
.id(commentdto.getId())
@@ -100,7 +96,7 @@ private long getLoginId() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String loginEmail = authentication.getName();
UserEntity loginUser = userRepository.findByEmailAddr(loginEmail)
- .orElseThrow(() -> new NoSuchElementException(ErrorMessages.THERE_IS_NO_USER.getMessage() + loginEmail));
+ .orElseThrow(() -> new BusinessException(UserErrorCode.THERE_IS_NO_USER));
return loginUser.getId();
}
}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/domain/comment/service/CommentService.java b/backend/orury/src/main/java/com/kernel360/orury/domain/comment/service/CommentService.java
index a2b880a..f5ffc55 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/domain/comment/service/CommentService.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/domain/comment/service/CommentService.java
@@ -7,16 +7,15 @@
import com.kernel360.orury.domain.comment.model.CommentRequest;
import com.kernel360.orury.domain.notification.service.NotifyService;
import com.kernel360.orury.domain.post.db.PostEntity;
-import com.kernel360.orury.domain.post.db.PostLikeEntity;
-import com.kernel360.orury.domain.post.db.PostLikePK;
import com.kernel360.orury.domain.post.db.PostRepository;
-import com.kernel360.orury.domain.post.model.PostLikeRequest;
import com.kernel360.orury.domain.user.db.UserRepository;
import com.kernel360.orury.global.constants.Constant;
-import com.kernel360.orury.global.message.errors.ErrorMessages;
+import com.kernel360.orury.global.error.code.CommentErrorCode;
+import com.kernel360.orury.global.error.code.PostErrorCode;
+import com.kernel360.orury.global.error.code.UserErrorCode;
+import com.kernel360.orury.global.error.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
-import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.time.LocalDateTime;
import java.util.List;
@@ -40,9 +39,9 @@ public class CommentService {
public CommentDto createComment(CommentRequest commentRequest, String userEmail) {
PostEntity postEntity = postRepository.findById(commentRequest.getPostId())
- .orElseThrow(() -> new RuntimeException(ErrorMessages.THERE_IS_NO_POST.getMessage() + commentRequest.getPostId()));
+ .orElseThrow(() -> new BusinessException(PostErrorCode.THERE_IS_NO_POST));
var user = userRepository.findByEmailAddr(userEmail)
- .orElseThrow(() -> new RuntimeException(ErrorMessages.THERE_IS_NO_USER.getMessage() + userEmail));
+ .orElseThrow(() -> new BusinessException(UserErrorCode.THERE_IS_NO_USER));
Long userId = user.getId();
CommentEntity commentEntity = CommentEntity.builder()
@@ -63,7 +62,7 @@ public CommentDto createComment(CommentRequest commentRequest, String userEmail)
Long notifyUserId = null;
if( commentEntity.getPId() != null ) {
notifyUserId = commentRepository.findById(commentEntity.getPId()).orElseThrow(
- () -> new RuntimeException(ErrorMessages.THERE_IS_NO_COMMENT.getMessage() + commentEntity.getPId())
+ () -> new BusinessException(CommentErrorCode.THERE_IS_NO_COMMENT)
).getUserId();
if (!Objects.equals(notifyUserId, saveEntity.getUserId())) {
sendNotificationToPostAuthor(notifyUserId, postEntity.getPostTitle() + "의 댓글 답변 달림");
@@ -90,7 +89,7 @@ public CommentDto updateComment(
){
Long id = commentRequest.getId();
Optional entity = commentRepository.findById(id);
- CommentEntity updateEntity = entity.orElseThrow(() -> new RuntimeException(ErrorMessages.THERE_IS_NO_COMMENT.getMessage() + id));
+ CommentEntity updateEntity = entity.orElseThrow(() -> new BusinessException(CommentErrorCode.THERE_IS_NO_COMMENT));
CommentDto updateDto = commentConverter.toDto(updateEntity);
updateDto.setCommentContent(commentRequest.getCommentContent());
updateDto.setUpdatedBy(Constant.ADMIN.getMessage());
@@ -114,10 +113,10 @@ public List findAllByPostId(Long postId) {
public boolean isWriter(String userEmail, Long id) {
var comment = commentRepository.findById(id).orElseThrow(
- () -> new RuntimeException(ErrorMessages.THERE_IS_NO_COMMENT.getMessage() + id)
+ () -> new BusinessException(CommentErrorCode.THERE_IS_NO_COMMENT)
);
var user = userRepository.findByEmailAddr(userEmail).orElseThrow(
- () -> new RuntimeException(ErrorMessages.THERE_IS_NO_USER.getMessage() + userEmail)
+ () -> new BusinessException(UserErrorCode.THERE_IS_NO_USER)
);
return Objects.equals(user.getId(), comment.getUserId());
}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/domain/post/controller/PostController.java b/backend/orury/src/main/java/com/kernel360/orury/domain/post/controller/PostController.java
index bcd6b16..d8cfc72 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/domain/post/controller/PostController.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/domain/post/controller/PostController.java
@@ -1,21 +1,14 @@
package com.kernel360.orury.domain.post.controller;
-import com.kernel360.orury.config.jwt.TokenProvider;
import com.kernel360.orury.domain.post.model.PostDto;
import com.kernel360.orury.domain.post.model.PostLikeDto;
import com.kernel360.orury.domain.post.model.PostLikeRequest;
import com.kernel360.orury.domain.post.model.PostRequest;
import com.kernel360.orury.domain.post.service.PostService;
-
import com.kernel360.orury.global.common.Api;
-
-import com.kernel360.orury.global.message.errors.ErrorMessages;
+import com.kernel360.orury.global.error.code.AuthorizationErrorCode;
import com.kernel360.orury.global.message.info.InfoMessages;
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.Jwts;
import lombok.RequiredArgsConstructor;
-
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
@@ -27,8 +20,6 @@
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
-
-import java.security.Key;
import java.util.Collection;
import java.util.List;
@@ -98,7 +89,7 @@ public ResponseEntity deletePost(@PathVariable Long postId) {
postService.deletePost(postId);
return ResponseEntity.ok(InfoMessages.POST_DELETED.getMessage() + postId);
}else{
- return ResponseEntity.status(HttpStatus.FORBIDDEN).body("삭제 "+ ErrorMessages.THERE_IS_NO_AUTHORITY.getMessage());
+ return ResponseEntity.status(HttpStatus.FORBIDDEN).body("삭제 "+ AuthorizationErrorCode.THERE_IS_NO_AUTHORITY.getMessage());
}
}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/domain/post/model/PostDto.java b/backend/orury/src/main/java/com/kernel360/orury/domain/post/model/PostDto.java
index 5d931f8..a2d78d1 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/domain/post/model/PostDto.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/domain/post/model/PostDto.java
@@ -33,6 +33,7 @@ public class PostDto {
private LocalDateTime updatedAt;
private String thumbnailUrl;
private List imageList = List.of();
+ private Long commentCnt;
private List commentList = List.of();
private Map> commentMap = Map.of();
@JsonProperty("is_like")
diff --git a/backend/orury/src/main/java/com/kernel360/orury/domain/post/service/PostConverter.java b/backend/orury/src/main/java/com/kernel360/orury/domain/post/service/PostConverter.java
index bad64c8..af8313b 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/domain/post/service/PostConverter.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/domain/post/service/PostConverter.java
@@ -2,9 +2,7 @@
import com.kernel360.orury.domain.board.db.BoardEntity;
import com.kernel360.orury.domain.board.db.BoardRepository;
-import com.kernel360.orury.domain.board.model.BoardDto;
import com.kernel360.orury.domain.comment.model.CommentDto;
-import com.kernel360.orury.domain.comment.model.CommentLikeDto;
import com.kernel360.orury.domain.comment.service.CommentConverter;
import com.kernel360.orury.domain.post.db.PostEntity;
import com.kernel360.orury.domain.post.db.PostLikeEntity;
@@ -13,7 +11,9 @@
import com.kernel360.orury.domain.post.model.PostLikeDto;
import com.kernel360.orury.domain.user.db.UserEntity;
import com.kernel360.orury.domain.user.db.UserRepository;
-import com.kernel360.orury.global.message.errors.ErrorMessages;
+import com.kernel360.orury.global.error.code.BoardErrorCode;
+import com.kernel360.orury.global.error.code.UserErrorCode;
+import com.kernel360.orury.global.error.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
@@ -40,6 +40,8 @@ public PostDto toDto(PostEntity postEntity) {
.map(commentConverter::toDto)
.toList();
+ long commentCnt = commentList.size();
+
// map으로 변환
Map> commentMap = new HashMap<>();
for (CommentDto comment : commentList) {
@@ -54,7 +56,7 @@ public PostDto toDto(PostEntity postEntity) {
// 게시글 작성자 userNickname 설정을 위한 entity
UserEntity userEntity = userRepository.findById(postEntity.getUserId())
- .orElseThrow(() -> new RuntimeException(ErrorMessages.THERE_IS_NO_USER.getMessage() + postEntity.getUserId()));
+ .orElseThrow(() -> new BusinessException(UserErrorCode.THERE_IS_NO_USER));
// 좋아요 수 및 유저 좋아요 세팅
long loginId = getLoginId();
@@ -73,7 +75,9 @@ public PostDto toDto(PostEntity postEntity) {
.thumbnailUrl(postEntity.getThumbnailUrl())
.imageList(postEntity.getImages() == null ? List.of() : Arrays.stream(postEntity.getImages().split(","))
.map(image -> getenv().get("IMGUR_URL") + image)
- .collect(Collectors.toList()))
+ .collect(Collectors.toList())
+ )
+ .commentCnt(commentCnt)
.commentList(commentList)
.commentMap(commentMap)
.isLike(isLike)
@@ -88,7 +92,7 @@ public PostDto toDto(PostEntity postEntity) {
public PostEntity toEntity(PostDto postDto) {
BoardEntity boardEntity = boardRepository.findById(postDto.getBoardId())
.orElseThrow(
- () -> new RuntimeException(ErrorMessages.THERE_IS_NO_BOARD.getMessage() + postDto.getBoardId())
+ () -> new BusinessException(BoardErrorCode.THERE_IS_NO_BOARD)
);
return PostEntity.builder()
@@ -129,7 +133,7 @@ private long getLoginId() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String loginEmail = authentication.getName();
UserEntity loginUser = userRepository.findByEmailAddr(loginEmail)
- .orElseThrow(() -> new NoSuchElementException(ErrorMessages.THERE_IS_NO_USER.getMessage() + loginEmail));
+ .orElseThrow(() -> new BusinessException(UserErrorCode.THERE_IS_NO_USER));
return loginUser.getId();
}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/domain/post/service/PostService.java b/backend/orury/src/main/java/com/kernel360/orury/domain/post/service/PostService.java
index fdcaf5b..7a0a991 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/domain/post/service/PostService.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/domain/post/service/PostService.java
@@ -11,15 +11,18 @@
import com.kernel360.orury.global.common.Api;
import com.kernel360.orury.global.common.Pagination;
import com.kernel360.orury.global.constants.Constant;
-import com.kernel360.orury.global.message.errors.ErrorMessages;
-
+import com.kernel360.orury.global.error.code.BoardErrorCode;
+import com.kernel360.orury.global.error.code.PostErrorCode;
+import com.kernel360.orury.global.error.code.UserErrorCode;
+import com.kernel360.orury.global.error.exception.BusinessException;
import lombok.RequiredArgsConstructor;
-
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
-import java.util.*;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
@RequiredArgsConstructor
@Service
@@ -35,10 +38,10 @@ public PostDto createPost(
String userEmail
) {
var user = userRepository.findByEmailAddr(userEmail)
- .orElseThrow(() -> new NoSuchElementException(ErrorMessages.THERE_IS_NO_USER.getMessage() + userEmail));
+ .orElseThrow(() -> new BusinessException(UserErrorCode.THERE_IS_NO_USER));
var boardEntity = boardRepository.findById(postRequest.getBoardId())
- .orElseThrow(() -> new RuntimeException(ErrorMessages.THERE_IS_NO_BOARD.getMessage()));
+ .orElseThrow(() -> new BusinessException(BoardErrorCode.THERE_IS_NO_BOARD));
var entity = PostEntity.builder()
.postTitle(postRequest.getPostTitle())
@@ -60,7 +63,7 @@ public PostDto createPost(
public PostDto getPost(Long id) {
Optional postEntityOptional = postRepository.findById(id);
PostEntity post = postEntityOptional.orElseThrow(
- () -> new RuntimeException(ErrorMessages.THERE_IS_NO_POST.getMessage() + id));
+ () -> new BusinessException(PostErrorCode.THERE_IS_NO_POST));
return postConverter.toDto(post);
}
@@ -70,7 +73,7 @@ public PostDto updatePost(
Long postId = postRequest.getId();
var postEntityOptional = postRepository.findById(postId);
var entity = postEntityOptional.orElseThrow(
- () -> new RuntimeException(ErrorMessages.THERE_IS_NO_POST.getMessage() + postId));
+ () -> new BusinessException(PostErrorCode.THERE_IS_NO_POST));
var dto = postConverter.toDto(entity);
dto.setPostTitle(postRequest.getPostTitle());
dto.setPostContent(postRequest.getPostContent());
@@ -112,11 +115,11 @@ public Api> getPostList(Pageable pageable) {
public boolean isWriter(String userEmail, Long postId) {
PostEntity post = postRepository.findById(postId).orElseThrow(
- () -> new RuntimeException(ErrorMessages.THERE_IS_NO_POST.getMessage() + postId)
+ () -> new BusinessException(PostErrorCode.THERE_IS_NO_POST)
);
UserEntity user = userRepository.findByEmailAddr(userEmail).orElseThrow(
- () -> new RuntimeException(ErrorMessages.THERE_IS_NO_USER.getMessage() + userEmail)
+ () -> new BusinessException(UserErrorCode.THERE_IS_NO_USER)
);
return Objects.equals(user.getId(), post.getUserId());
diff --git a/backend/orury/src/main/java/com/kernel360/orury/domain/user/db/UserEntity.java b/backend/orury/src/main/java/com/kernel360/orury/domain/user/db/UserEntity.java
index 78e897a..cd18603 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/domain/user/db/UserEntity.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/domain/user/db/UserEntity.java
@@ -59,9 +59,7 @@ public class UserEntity extends BaseEntity {
private Boolean isWithdrawal;
private String withdrawalId;
private LocalDateTime withdrawalAt;
- private String remark1;
- private String remark2;
- private String remark3;
+ private String remark;
@ManyToMany
@JoinTable(
diff --git a/backend/orury/src/main/java/com/kernel360/orury/domain/user/service/CustomUserDetailsService.java b/backend/orury/src/main/java/com/kernel360/orury/domain/user/service/CustomUserDetailsService.java
index 4425660..117e74b 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/domain/user/service/CustomUserDetailsService.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/domain/user/service/CustomUserDetailsService.java
@@ -1,19 +1,18 @@
package com.kernel360.orury.domain.user.service;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import com.kernel360.orury.global.message.errors.ErrorMessages;
+import com.kernel360.orury.domain.user.db.UserEntity;
+import com.kernel360.orury.domain.user.db.UserRepository;
+import com.kernel360.orury.global.error.code.UserErrorCode;
+import com.kernel360.orury.global.error.exception.BusinessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
-import com.kernel360.orury.domain.user.db.UserEntity;
-import com.kernel360.orury.domain.user.db.UserRepository;
+import java.util.List;
+import java.util.stream.Collectors;
@Component("userDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
@@ -28,12 +27,12 @@ public CustomUserDetailsService(UserRepository userRepository) {
public UserDetails loadUserByUsername(final String emailAddr) {
return userRepository.findOneWithAuthoritiesByEmailAddr(emailAddr)
.map(user -> createUser(emailAddr, user))
- .orElseThrow(() -> new UsernameNotFoundException(emailAddr + ErrorMessages.NOT_EXIST_USER_EMAIL));
+ .orElseThrow(() -> new BusinessException(UserErrorCode.THERE_IS_NO_USER));
}
private org.springframework.security.core.userdetails.User createUser(String emailAddr, UserEntity user) {
if (!user.isActivated()) {
- throw new RuntimeException(emailAddr + ErrorMessages.NOT_ACTIVATED);
+ throw new BusinessException(UserErrorCode.NOT_ACTIVATED);
}
List grantedAuthorities = user.getAuthorities().stream()
diff --git a/backend/orury/src/main/java/com/kernel360/orury/domain/user/service/UserService.java b/backend/orury/src/main/java/com/kernel360/orury/domain/user/service/UserService.java
index d91342f..d0178f7 100644
--- a/backend/orury/src/main/java/com/kernel360/orury/domain/user/service/UserService.java
+++ b/backend/orury/src/main/java/com/kernel360/orury/domain/user/service/UserService.java
@@ -1,22 +1,19 @@
package com.kernel360.orury.domain.user.service;
-import java.time.LocalDateTime;
-import java.util.Collections;
-
import com.kernel360.orury.domain.user.db.AuthorityEntity;
+import com.kernel360.orury.domain.user.db.UserEntity;
+import com.kernel360.orury.domain.user.db.UserRepository;
+import com.kernel360.orury.domain.user.model.UserDto;
+import com.kernel360.orury.global.common.SecurityUtil;
import com.kernel360.orury.global.constants.Constant;
-import com.kernel360.orury.global.message.errors.ErrorMessages;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import com.kernel360.orury.global.error.code.UserErrorCode;
+import com.kernel360.orury.global.error.exception.BusinessException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import com.kernel360.orury.domain.user.db.UserEntity;
-import com.kernel360.orury.domain.user.db.UserRepository;
-import com.kernel360.orury.global.exception.DuplicateMemberException;
-import com.kernel360.orury.global.exception.NotFoundMemberException;
-import com.kernel360.orury.domain.user.model.UserDto;
-import com.kernel360.orury.global.common.SecurityUtil;
+import java.time.LocalDateTime;
+import java.util.Collections;
@Service
public class UserService {
@@ -31,7 +28,7 @@ public UserService(UserRepository userRepository, PasswordEncoder passwordEncode
@Transactional
public UserDto signup(UserDto userDto) {
if (userRepository.findOneWithAuthoritiesByEmailAddr(userDto.getEmailAddr()).orElse(null) != null) {
- throw new DuplicateMemberException("이미 가입되어 있는 유저입니다.");
+ throw new BusinessException(UserErrorCode.ALREADY_EXISTING_USER);
}
AuthorityEntity authority = AuthorityEntity.builder()
@@ -63,14 +60,14 @@ public UserDto getMyUserWithAuthorities() {
return UserDto.from(
SecurityUtil.getCurrentUsername()
.flatMap(userRepository::findOneWithAuthoritiesByEmailAddr)
- .orElseThrow(() -> new NotFoundMemberException("Member not found"))
+ .orElseThrow(() -> new BusinessException(UserErrorCode.THERE_IS_NO_USER))
);
}
@Transactional(readOnly = true)
public Long getUserIdByEmail(String email){
return userRepository.findByEmailAddr(email).orElseThrow(
- () -> new UsernameNotFoundException(ErrorMessages.THERE_IS_NO_USER.getMessage())
+ () -> new BusinessException(UserErrorCode.THERE_IS_NO_USER)
).getId();
}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/global/error/GlobalExceptionHandler.java b/backend/orury/src/main/java/com/kernel360/orury/global/error/GlobalExceptionHandler.java
new file mode 100644
index 0000000..a6c66af
--- /dev/null
+++ b/backend/orury/src/main/java/com/kernel360/orury/global/error/GlobalExceptionHandler.java
@@ -0,0 +1,24 @@
+package com.kernel360.orury.global.error;
+
+import com.kernel360.orury.global.common.ApiResponse;
+import com.kernel360.orury.global.error.code.ServerErrorCode;
+import com.kernel360.orury.global.error.dto.ErrorResponse;
+import com.kernel360.orury.global.error.exception.BusinessException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+ @ExceptionHandler(BusinessException.class)
+ public ResponseEntity handleBusinessException(BusinessException e) {
+ return ResponseEntity.status(e.getErrorCode().getStatus()).body(ErrorResponse.of(e.getErrorCode()));
+ }
+
+// @ExceptionHandler(Exception.class)
+// public ResponseEntity handleException(Exception e){
+// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ApiResponse.error(HttpStatus.INTERNAL_SERVER_ERROR, 500, ServerErrorCode.INTERNAL_SERVER_ERROR.getMessage()));
+// }
+
+}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/global/error/code/AuthorizationErrorCode.java b/backend/orury/src/main/java/com/kernel360/orury/global/error/code/AuthorizationErrorCode.java
new file mode 100644
index 0000000..90dd832
--- /dev/null
+++ b/backend/orury/src/main/java/com/kernel360/orury/global/error/code/AuthorizationErrorCode.java
@@ -0,0 +1,25 @@
+package com.kernel360.orury.global.error.code;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public enum AuthorizationErrorCode implements ErrorCode {
+ THERE_IS_NO_AUTHORITY(403, 403, "권한이 없습니다");
+
+ private final int status;
+ private final int code;
+ private final String message;
+
+ @Override
+ public int getStatus() { return status; }
+
+ @Override
+ public int getCode() {
+ return code;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/global/error/code/BoardErrorCode.java b/backend/orury/src/main/java/com/kernel360/orury/global/error/code/BoardErrorCode.java
new file mode 100644
index 0000000..850b796
--- /dev/null
+++ b/backend/orury/src/main/java/com/kernel360/orury/global/error/code/BoardErrorCode.java
@@ -0,0 +1,26 @@
+package com.kernel360.orury.global.error.code;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public enum BoardErrorCode implements ErrorCode {
+ THERE_IS_NO_BOARD(400, 410, "해당 게시판이 존재하지 않습니다.");
+
+ private final int status;
+ private final int code;
+ private final String message;
+
+ @Override
+ public int getStatus() { return status; }
+
+ @Override
+ public int getCode() {
+ return code;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+}
+
diff --git a/backend/orury/src/main/java/com/kernel360/orury/global/error/code/CertificationErrorCode.java b/backend/orury/src/main/java/com/kernel360/orury/global/error/code/CertificationErrorCode.java
new file mode 100644
index 0000000..858c473
--- /dev/null
+++ b/backend/orury/src/main/java/com/kernel360/orury/global/error/code/CertificationErrorCode.java
@@ -0,0 +1,30 @@
+package com.kernel360.orury.global.error.code;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public enum CertificationErrorCode implements ErrorCode {
+ MALFORMED_JWT(401, 401, "잘못된 JWT 서명입니다."),
+ EXPIRED_ACCESS_JWT(401, 411, "만료된 Access Token 입니다."),
+ UNSUPPORTED_JWT(401, 401, "지원되지 않는 JWT 토큰입니다."),
+ EXPIRED_REFRESH_JWT(401, 412, "만료된 Refresh Token 입니다."),
+ ILLEGAL_ARGUMENT_JWT(401, 401, "JWT 토큰이 잘못되었습니다."),
+ ILLEGAL_REFRESH_JWT(401, 401, "유효하지 않은 Refresh Token 입니다.");
+
+ private final int status;
+ private final int code;
+ private final String message;
+
+ @Override
+ public int getStatus() { return status; }
+
+ @Override
+ public int getCode() {
+ return code;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/global/error/code/CommentErrorCode.java b/backend/orury/src/main/java/com/kernel360/orury/global/error/code/CommentErrorCode.java
new file mode 100644
index 0000000..f784d28
--- /dev/null
+++ b/backend/orury/src/main/java/com/kernel360/orury/global/error/code/CommentErrorCode.java
@@ -0,0 +1,25 @@
+package com.kernel360.orury.global.error.code;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public enum CommentErrorCode implements ErrorCode{
+ THERE_IS_NO_COMMENT(400, 430, "해당 댓글이 존재하지 않습니다.");
+
+ private final int status;
+ private final int code;
+ private final String message;
+
+ @Override
+ public int getStatus() { return status; }
+
+ @Override
+ public int getCode() {
+ return code;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/global/error/code/ErrorCode.java b/backend/orury/src/main/java/com/kernel360/orury/global/error/code/ErrorCode.java
new file mode 100644
index 0000000..2b9a474
--- /dev/null
+++ b/backend/orury/src/main/java/com/kernel360/orury/global/error/code/ErrorCode.java
@@ -0,0 +1,7 @@
+package com.kernel360.orury.global.error.code;
+
+public interface ErrorCode {
+ int getStatus();
+ int getCode();
+ String getMessage();
+}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/global/error/code/PostErrorCode.java b/backend/orury/src/main/java/com/kernel360/orury/global/error/code/PostErrorCode.java
new file mode 100644
index 0000000..98c6e25
--- /dev/null
+++ b/backend/orury/src/main/java/com/kernel360/orury/global/error/code/PostErrorCode.java
@@ -0,0 +1,25 @@
+package com.kernel360.orury.global.error.code;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public enum PostErrorCode implements ErrorCode {
+ THERE_IS_NO_POST(400, 420, "해당 게시글이 존재하지 않습니다.");
+
+ private final int status;
+ private final int code;
+ private final String message;
+
+ @Override
+ public int getStatus() { return status; }
+
+ @Override
+ public int getCode() {
+ return code;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/global/error/code/ServerErrorCode.java b/backend/orury/src/main/java/com/kernel360/orury/global/error/code/ServerErrorCode.java
new file mode 100644
index 0000000..460407c
--- /dev/null
+++ b/backend/orury/src/main/java/com/kernel360/orury/global/error/code/ServerErrorCode.java
@@ -0,0 +1,25 @@
+package com.kernel360.orury.global.error.code;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public enum ServerErrorCode implements ErrorCode {
+ INTERNAL_SERVER_ERROR(500, 500, "서버 에러가 발생했습니다.");
+
+ private final int status;
+ private final int code;
+ private final String message;
+
+ @Override
+ public int getStatus() { return status; }
+
+ @Override
+ public int getCode() {
+ return code;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/global/error/code/UserErrorCode.java b/backend/orury/src/main/java/com/kernel360/orury/global/error/code/UserErrorCode.java
new file mode 100644
index 0000000..b25ca94
--- /dev/null
+++ b/backend/orury/src/main/java/com/kernel360/orury/global/error/code/UserErrorCode.java
@@ -0,0 +1,27 @@
+package com.kernel360.orury.global.error.code;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public enum UserErrorCode implements ErrorCode {
+ THERE_IS_NO_USER(400, 400,"해당 유저가 존재하지 않습니다."),
+ ALREADY_EXISTING_USER(400, 401, "이미 존재하는 유저입니다."),
+ NOT_ACTIVATED(400, 402, "휴면 처리된 회원입니다.");
+
+ private final int status;
+ private final int code;
+ private final String message;
+
+ @Override
+ public int getStatus() { return status; }
+
+ @Override
+ public int getCode() {
+ return code;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/global/error/dto/ErrorResponse.java b/backend/orury/src/main/java/com/kernel360/orury/global/error/dto/ErrorResponse.java
new file mode 100644
index 0000000..628376d
--- /dev/null
+++ b/backend/orury/src/main/java/com/kernel360/orury/global/error/dto/ErrorResponse.java
@@ -0,0 +1,29 @@
+package com.kernel360.orury.global.error.dto;
+
+import com.kernel360.orury.global.error.code.ErrorCode;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+@Getter
+@NoArgsConstructor
+public class ErrorResponse {
+// private int status;
+ private int code;
+ private String message;
+
+ @Builder
+ public ErrorResponse(String message, int code, int status) {
+// this.status = status;
+ this.code = code;
+ this.message = message;
+ }
+
+ public static ErrorResponse of(ErrorCode errorCode) {
+ return ErrorResponse.builder()
+// .status(errorCode.getStatus())
+ .code(errorCode.getCode())
+ .message(errorCode.getMessage())
+ .build();
+ }
+}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/global/error/exception/BusinessException.java b/backend/orury/src/main/java/com/kernel360/orury/global/error/exception/BusinessException.java
new file mode 100644
index 0000000..e72286d
--- /dev/null
+++ b/backend/orury/src/main/java/com/kernel360/orury/global/error/exception/BusinessException.java
@@ -0,0 +1,14 @@
+package com.kernel360.orury.global.error.exception;
+
+import com.kernel360.orury.global.error.code.ErrorCode;
+import lombok.Getter;
+import org.springframework.http.HttpStatus;
+
+@Getter
+public class BusinessException extends RuntimeException {
+ private final ErrorCode errorCode;
+
+ public BusinessException(ErrorCode errorCode) {
+ this.errorCode = errorCode;
+ }
+}
\ No newline at end of file
diff --git a/backend/orury/src/main/java/com/kernel360/orury/global/exception/DuplicateMemberException.java b/backend/orury/src/main/java/com/kernel360/orury/global/exception/DuplicateMemberException.java
deleted file mode 100644
index a323b52..0000000
--- a/backend/orury/src/main/java/com/kernel360/orury/global/exception/DuplicateMemberException.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.kernel360.orury.global.exception;
-
-public class DuplicateMemberException extends RuntimeException {
-
- public DuplicateMemberException() {
- super();
- }
-
- public DuplicateMemberException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public DuplicateMemberException(String message) {
- super(message);
- }
-
- public DuplicateMemberException(Throwable cause) {
- super(cause);
- }
-
-}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/global/exception/GlobalExceptionHandler.java b/backend/orury/src/main/java/com/kernel360/orury/global/exception/GlobalExceptionHandler.java
deleted file mode 100644
index a55a59d..0000000
--- a/backend/orury/src/main/java/com/kernel360/orury/global/exception/GlobalExceptionHandler.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.kernel360.orury.global.exception;
-
-import com.kernel360.orury.global.common.ApiResponse;
-import com.kernel360.orury.global.message.errors.ErrorMessages;
-import io.jsonwebtoken.ExpiredJwtException;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.ControllerAdvice;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.bind.annotation.RestControllerAdvice;
-
-import java.util.NoSuchElementException;
-
-@RestControllerAdvice
-public class GlobalExceptionHandler {
-
- @ExceptionHandler(TokenExpiredException.class)
- public ResponseEntity handleTokenExpiredException(TokenExpiredException ex){
- return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(ApiResponse.error(HttpStatus.UNAUTHORIZED, 401, ErrorMessages.EXPIRED_JWT.getMessage()));
- }
-
- @ExceptionHandler(Exception.class)
- public ResponseEntity handleException(Exception ex){
- return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ApiResponse.error(HttpStatus.INTERNAL_SERVER_ERROR, 500, ErrorMessages.INTERNAL_SERVER_ERROR.getMessage()));
- }
-
- @ExceptionHandler(ExpiredJwtException.class)
- public ResponseEntity handleTokenExpiredException(ExpiredJwtException ex){
- return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(ApiResponse.error(HttpStatus.UNAUTHORIZED, 401, ErrorMessages.EXPIRED_JWT.getMessage()));
- }
- @ExceptionHandler(TokenNotFoundException.class)
- public ResponseEntity handleTokenNotFoundException(TokenNotFoundException ex){
- return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(ApiResponse.error(HttpStatus.UNAUTHORIZED, 402, ErrorMessages.ILLEGAL_REFRESH_JWT.getMessage()));
- }
-
- @ExceptionHandler({IllegalArgumentException.class, NoSuchElementException.class})
- public ResponseEntity userNotFoundException(NoSuchElementException ex){
- return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.error(HttpStatus.BAD_REQUEST, 400, ErrorMessages.THERE_IS_NO_USER.getMessage()));
- }
-
- @ExceptionHandler(RuntimeException.class)
- public ResponseEntity boardNotFoundException(RuntimeException ex){
- return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResponse.error(HttpStatus.BAD_REQUEST, 400, ex.getMessage()));
- }
-
- @ExceptionHandler(RefreshExpiredJwtException.class)
- public ResponseEntity handleRefreshTokenExpiredException(RefreshExpiredJwtException ex){
- return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(ApiResponse.error(HttpStatus.UNAUTHORIZED, 402, ErrorMessages.EXPIRED_REFRESH_JWT.getMessage()));
- }
-}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/global/exception/NotFoundMemberException.java b/backend/orury/src/main/java/com/kernel360/orury/global/exception/NotFoundMemberException.java
deleted file mode 100644
index fde361d..0000000
--- a/backend/orury/src/main/java/com/kernel360/orury/global/exception/NotFoundMemberException.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.kernel360.orury.global.exception;
-
-public class NotFoundMemberException extends RuntimeException {
- public NotFoundMemberException() {
- super();
- }
-
- public NotFoundMemberException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public NotFoundMemberException(String message) {
- super(message);
- }
-
- public NotFoundMemberException(Throwable cause) {
- super(cause);
- }
-}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/global/exception/RefreshExpiredJwtException.java b/backend/orury/src/main/java/com/kernel360/orury/global/exception/RefreshExpiredJwtException.java
deleted file mode 100644
index 849f15f..0000000
--- a/backend/orury/src/main/java/com/kernel360/orury/global/exception/RefreshExpiredJwtException.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.kernel360.orury.global.exception;
-
-public class RefreshExpiredJwtException extends RuntimeException{
- public RefreshExpiredJwtException(String message){
- super(message);
- }
-}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/global/exception/TokenExpiredException.java b/backend/orury/src/main/java/com/kernel360/orury/global/exception/TokenExpiredException.java
deleted file mode 100644
index 70ad667..0000000
--- a/backend/orury/src/main/java/com/kernel360/orury/global/exception/TokenExpiredException.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.kernel360.orury.global.exception;
-
-public class TokenExpiredException extends RuntimeException{
- public TokenExpiredException(String message) {
- super(message);
- }
-}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/global/exception/TokenNotFoundException.java b/backend/orury/src/main/java/com/kernel360/orury/global/exception/TokenNotFoundException.java
deleted file mode 100644
index a0e7df7..0000000
--- a/backend/orury/src/main/java/com/kernel360/orury/global/exception/TokenNotFoundException.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.kernel360.orury.global.exception;
-
-public class TokenNotFoundException extends RuntimeException{
- public TokenNotFoundException(String message) {
- super(message);
- }
-}
diff --git a/backend/orury/src/main/java/com/kernel360/orury/global/message/errors/ErrorMessages.java b/backend/orury/src/main/java/com/kernel360/orury/global/message/errors/ErrorMessages.java
deleted file mode 100644
index 8121fd0..0000000
--- a/backend/orury/src/main/java/com/kernel360/orury/global/message/errors/ErrorMessages.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.kernel360.orury.global.message.errors;
-
-import lombok.Getter;
-
-@Getter
-public enum ErrorMessages {
- // 게시판
- THERE_IS_NO_BOARD("게시판이 존재하지 않습니다."),
- THERE_IS_NO_POST("게시글이 존재하지 않습니다."),
- THERE_IS_NO_COMMENT("댓글이 존재하지 않습니다."),
- THERE_IS_NO_USER("유저가 존재하지 않습니다."),
- THERE_IS_NO_AUTHORITY("권한이 없습니다"),
-
- // 회원
- NOT_EXIST_USER_EMAIL("존재하지 않는 회원입니다. (email 계정 없음)"),
- NOT_ACTIVATED("휴면 처리된 회원입니다."),
-
- // 인증
- MALFORMED_JWT("잘못된 JWT 서명입니다."),
- EXPIRED_JWT("만료된 JWT 서명입니다."),
- UNSUPPORTED_JWT("지원되지 않는 JWT 토큰입니다."),
- EXPIRED_REFRESH_JWT("만료된 REFRESH JWT 서명입니다."),
- ILLEGAL_ARGUMENT_JWT("JWT 토큰이 잘못되었습니다."),
- ILLEGAL_REFRESH_JWT("유효하지 않은 JWT리프레시 토큰입니다."),
-
- // 서버
- INTERNAL_SERVER_ERROR("서버 에러가 발생했습니다.")
- ;
-
- private final String message;
-
- ErrorMessages(String message) {
- this.message = message;
- }
-
-}
diff --git a/backend/orury/src/main/resources/application.yml b/backend/orury/src/main/resources/application.yml
index b5f3b9f..380aa42 100644
--- a/backend/orury/src/main/resources/application.yml
+++ b/backend/orury/src/main/resources/application.yml
@@ -12,25 +12,36 @@ spring:
generate-ddl: true
hibernate:
ddl-auto: validate
+ cache:
+ use_second_level_cache: false
+ use_query_cache: false
properties:
hibernate:
format_sql: true
use_sql_comments: true
show_sql: true
+ persistence:
+ sharedCache:
+ mode:NONE
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
-# url: ${LOCAL_DB_URL} # configuration에서 설정 필요
+ # url: ${LOCAL_DB_URL} # configuration에서 설정 필요
url: ENC(4t9k8jNC5SIDd1hpsqRJiw5NgwtRAZ9l2cY42PcN3v6GNDC61KXk4X3nYwwUdW4+aC6g41zh14HyfWg+2fPmfuTXHg7aw+vTvL9Oomq1wEKM2r2ZHJbhmakdpmbeMVjVALC/MSk28Tp4a5sBhUFRWdpaFO2qQcpdUHUd9KsuJh0=)
-# username: ${LOCAL_DB_USERNAME}
+ # username: ${LOCAL_DB_USERNAME}
username: ENC(2STroDy2TfWobkrTroFwbRcxLke05156ZFMrqwKmVssNcN4foSX4I6ax8YAgdW3R)
-# password: ${LOCAL_DB_USER_PASSWORD}
+ # password: ${LOCAL_DB_USER_PASSWORD}
password: ENC(a8l7l/AYNz2x1HPYyu+urOBwVcBhQkeWgTi6Fvt+lQFq1QyHsL8yyi5+wr7lh26P)
+ flyway:
+ enabled: true
+ baseline-on-migrate: true
jwt:
header: Authorization
#HS512 알고리즘을 사용할 것이기 때문에 512bit, 즉 64byte 이상의 secret key를 사용해야 한다.
#echo 'silvernine-tech-spring-boot-jwt-tutorial-secret-silvernine-tech-spring-boot-jwt-tutorial-secret'|base64
-# secret: ${LOCAL_JWT_SECRET_KEY}
+ # secret: ${LOCAL_JWT_SECRET_KEY}
secret: ENC(XNkGVBeK1sJZhLhri+zz7pJOhHCvfif265mvT8OUIbOGeQcOCtHNnG2s3qjsKNe2u+dLoNVQBzbF1bKUfDxi8Po5tL7jQbZMPA33Dg1QMQFQWV46IyrYnLykYXQQvpin/SNPXW04ECDoRLF3TNwcS22D8uWEwe8L2wtcauyHeO1z+J6lUQArPHy76O2pzC7FHlBjOTw3STd23e3dd1WBQtHAYVmOIvNuPreulzSaHXc=)
access-validity: 1800
refresh-validity: 7200
+ cookie-name: access-token
+ refresh-cookie-name: refresh-token
diff --git a/backend/orury/src/main/resources/data.sql b/backend/orury/src/main/resources/data.sql
index 342180b..a8c339c 100644
--- a/backend/orury/src/main/resources/data.sql
+++ b/backend/orury/src/main/resources/data.sql
@@ -3,9 +3,9 @@ values ('admin@gmail.com', '$2a$08$lDnHPz7eUkSi6ao14Twuau08mzhWrL4kyZGGU5xfiGALO
insert into user (email_addr, password, activated, created_at, created_by)
values ('shin@gmail.com', '$2a$08$UkVvwpULis18S19S5pZFn.YHPZt3oaqHZnDwqbCW9pft6uFtkXKDC', 1, now(), 'admin');
-insert into authority (authority_name, )
+insert into authority (name)
values ('ROLE_USER');
-insert into authority (authority_name)
+insert into authority (name)
values ('ROLE_ADMIN');
insert into user_authority (user_id, authority_name)
diff --git a/backend/orury/src/main/resources/db/migration/V1.0.0__alter_column_in_user.sql b/backend/orury/src/main/resources/db/migration/V1.0.0__alter_column_in_user.sql
new file mode 100644
index 0000000..5dcd2df
--- /dev/null
+++ b/backend/orury/src/main/resources/db/migration/V1.0.0__alter_column_in_user.sql
@@ -0,0 +1,6 @@
+-- 기존 remark2, 3 삭제
+alter table user drop column remark2;
+alter table user drop column remark3;
+
+-- remark1 -> remark 변경
+alter table user change remark1 remark varchar(255);
diff --git a/backend/orury/src/main/resources/templates/index.html b/backend/orury/src/main/resources/templates/index.html
index 6d2ddff..490b6a9 100644
--- a/backend/orury/src/main/resources/templates/index.html
+++ b/backend/orury/src/main/resources/templates/index.html
@@ -40,7 +40,6 @@
-
!-- ======= Header ======= -->