From d443fd7e222e0b7e23d31cdb6a420f9e8267950f Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Sun, 14 Jul 2024 15:11:18 +0900 Subject: [PATCH 01/17] =?UTF-8?q?Feat=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85,=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=A0=91=EA=B7=BC=20=ED=97=88=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../space_spring/config/SecurityConfig.java | 37 +++++++++++++++++++ .../space_spring/service/UserService.java | 3 ++ 2 files changed, 40 insertions(+) create mode 100644 src/main/java/space/space_spring/config/SecurityConfig.java diff --git a/src/main/java/space/space_spring/config/SecurityConfig.java b/src/main/java/space/space_spring/config/SecurityConfig.java new file mode 100644 index 00000000..ace7cd44 --- /dev/null +++ b/src/main/java/space/space_spring/config/SecurityConfig.java @@ -0,0 +1,37 @@ +package space.space_spring.config; + +import org.springframework.boot.autoconfigure.security.servlet.PathRequest; +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.web.SecurityFilterChain; + +@Configuration +@EnableWebSecurity +public class SecurityConfig { + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + // csrf 설정을 disable + .csrf((csrfConfig) -> + csrfConfig.disable() + ) + // h2 console 화면을 사용하기 위해 해당 옵션들 disable + .headers((headerConfig) -> + headerConfig.frameOptions(frameOptionsConfig -> + frameOptionsConfig.disable() + ) + ) + // 요청별 권한 설정 + .authorizeHttpRequests((authorizeRequests) -> + authorizeRequests + .requestMatchers(PathRequest.toH2Console()).permitAll() + .requestMatchers("/", "/user/signup", "/user/login").permitAll() + .anyRequest().authenticated() + ); + + return http.build(); + } +} diff --git a/src/main/java/space/space_spring/service/UserService.java b/src/main/java/space/space_spring/service/UserService.java index 9a054482..ef1e0b94 100644 --- a/src/main/java/space/space_spring/service/UserService.java +++ b/src/main/java/space/space_spring/service/UserService.java @@ -55,6 +55,9 @@ public PostUserLoginResponse login(PostUserLoginRequest postUserLoginRequest) { // TODO 3. JWT 발급 String jwt = jwtProvider.generateToken(userByEmail); + // TODO 4. JWT db에 insert + + return new PostUserLoginResponse(jwt); } From 5f6b4463e8d5b64a5af0f19d0a3f5f9b8f56867e Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Sun, 14 Jul 2024 15:23:41 +0900 Subject: [PATCH 02/17] =?UTF-8?q?Feat=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=8B=9C=20db=EC=97=90=20jwt=20=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/space/space_spring/domain/User.java | 4 ++++ src/main/java/space/space_spring/service/UserService.java | 2 +- src/main/resources/application.yml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/space/space_spring/domain/User.java b/src/main/java/space/space_spring/domain/User.java index 7db786bd..b15bc936 100644 --- a/src/main/java/space/space_spring/domain/User.java +++ b/src/main/java/space/space_spring/domain/User.java @@ -36,4 +36,8 @@ public void saveUser(String email, String password, String userName) { initializeBaseEntityFields(); } + public void saveJWTtoLoginUser(String jwt) { + this.jwt = jwt; + } + } diff --git a/src/main/java/space/space_spring/service/UserService.java b/src/main/java/space/space_spring/service/UserService.java index ef1e0b94..053109e0 100644 --- a/src/main/java/space/space_spring/service/UserService.java +++ b/src/main/java/space/space_spring/service/UserService.java @@ -56,7 +56,7 @@ public PostUserLoginResponse login(PostUserLoginRequest postUserLoginRequest) { String jwt = jwtProvider.generateToken(userByEmail); // TODO 4. JWT db에 insert - + userByEmail.saveJWTtoLoginUser(jwt); return new PostUserLoginResponse(jwt); } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 52fc80a1..4c55f267 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -11,7 +11,7 @@ spring: jpa: hibernate: - ddl-auto: update # table을 전부 drop했다가 다시 생성 -> 테스트용 + ddl-auto: update # create : 존재하는 table을 전부 drop했다가 다시 생성 -> 테스트용 properties: hibernate: format_sql: true From 32cf49643d1ce8dd8602ad726c4dcbb3fe54dadc Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Sun, 14 Jul 2024 17:13:35 +0900 Subject: [PATCH 03/17] =?UTF-8?q?refactor=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=EC=8B=9C=20responseHeader=EC=97=90=20jwt=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/UserController.java | 9 ++++--- .../dto/PostUserLoginResponse.java | 2 +- .../interceptor/JwtAuthInterceptor.java | 27 +++++++++++++++++++ .../space_spring/service/UserService.java | 4 +-- 4 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 src/main/java/space/space_spring/interceptor/JwtAuthInterceptor.java diff --git a/src/main/java/space/space_spring/controller/UserController.java b/src/main/java/space/space_spring/controller/UserController.java index 57b291ce..77ee6464 100644 --- a/src/main/java/space/space_spring/controller/UserController.java +++ b/src/main/java/space/space_spring/controller/UserController.java @@ -1,5 +1,6 @@ package space.space_spring.controller; +import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.BindingResult; @@ -32,7 +33,6 @@ public class UserController { */ @PostMapping("/signup") public BaseResponse signup(@Validated @RequestBody PostUserSignupRequest postUserSignupRequest, BindingResult bindingResult) { - log.info(" Signup request: {}", postUserSignupRequest); if (bindingResult.hasErrors()) { throw new UserException(INVALID_USER_VALUE, getErrorMessage(bindingResult)); } @@ -43,11 +43,14 @@ public BaseResponse signup(@Validated @RequestBody PostU * 로그인 */ @PostMapping("/login") - public BaseResponse login(@Validated @RequestBody PostUserLoginRequest postUserLoginRequest, BindingResult bindingResult) { + public BaseResponse login(@Validated @RequestBody PostUserLoginRequest postUserLoginRequest, BindingResult bindingResult, HttpServletResponse response) { if (bindingResult.hasErrors()) { throw new UserException(INVALID_USER_VALUE, getErrorMessage(bindingResult)); } - return new BaseResponse<>(userService.login(postUserLoginRequest)); + + String jwt = userService.login(postUserLoginRequest); + response.setHeader("Authorization", "Bearer " + jwt); + return new BaseResponse<>(new PostUserLoginResponse("로그인 성공")); } diff --git a/src/main/java/space/space_spring/dto/PostUserLoginResponse.java b/src/main/java/space/space_spring/dto/PostUserLoginResponse.java index 88ced6ab..14aa5a5f 100644 --- a/src/main/java/space/space_spring/dto/PostUserLoginResponse.java +++ b/src/main/java/space/space_spring/dto/PostUserLoginResponse.java @@ -7,5 +7,5 @@ @AllArgsConstructor public class PostUserLoginResponse { - private String jwt; + private String successMsg; } diff --git a/src/main/java/space/space_spring/interceptor/JwtAuthInterceptor.java b/src/main/java/space/space_spring/interceptor/JwtAuthInterceptor.java new file mode 100644 index 00000000..dc7b76f3 --- /dev/null +++ b/src/main/java/space/space_spring/interceptor/JwtAuthInterceptor.java @@ -0,0 +1,27 @@ +package space.space_spring.interceptor; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; +import space.space_spring.JwtProvider; +import space.space_spring.service.UserService; + +@Component +@RequiredArgsConstructor +public class JwtAuthInterceptor implements HandlerInterceptor { + + private static final String JWT_TOKEN_PREFIX = "Bearer "; + + private final JwtProvider jwtProvider; + private final UserService userService; + +// @Override +// public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { +// String accessToken = request.getHeader(HttpHeaders.AUTHORIZATION); +// +// } +} diff --git a/src/main/java/space/space_spring/service/UserService.java b/src/main/java/space/space_spring/service/UserService.java index 053109e0..8a330b1d 100644 --- a/src/main/java/space/space_spring/service/UserService.java +++ b/src/main/java/space/space_spring/service/UserService.java @@ -45,7 +45,7 @@ private void validateEmail(String email) { } @Transactional - public PostUserLoginResponse login(PostUserLoginRequest postUserLoginRequest) { + public String login(PostUserLoginRequest postUserLoginRequest) { // TODO 1. 이메일 존재 여부 확인(아이디 존재 여부 확인) User userByEmail = findUserByEmail(postUserLoginRequest.getEmail()); @@ -58,7 +58,7 @@ public PostUserLoginResponse login(PostUserLoginRequest postUserLoginRequest) { // TODO 4. JWT db에 insert userByEmail.saveJWTtoLoginUser(jwt); - return new PostUserLoginResponse(jwt); + return jwt; } private User findUserByEmail(String email) { From e794032cbcea03866383f392d3d9dbbf265398b9 Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Mon, 15 Jul 2024 11:57:21 +0900 Subject: [PATCH 04/17] =?UTF-8?q?Feat=20jwt=20=EA=B4=80=EB=A0=A8=20excepti?= =?UTF-8?q?on,=20interceptor=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/space/space_spring/JwtProvider.java | 53 ++++++++++++++++--- .../controller/TestController.java | 6 +++ .../bad_request/JwtBadRequestException.java | 15 ++++++ .../jwt/bad_request/JwtNoTokenException.java | 16 ++++++ .../JwtUnsupportedTokenException.java | 15 ++++++ .../JwtExpiredTokenException.java | 16 ++++++ .../JwtInvalidTokenException.java | 15 ++++++ .../JwtMalformedTokenException.java | 15 ++++++ .../JwtUnauthorizedTokenException.java | 18 +++++++ .../interceptor/JwtAuthInterceptor.java | 48 ++++++++++++++--- .../space_spring/service/UserService.java | 2 +- 11 files changed, 203 insertions(+), 16 deletions(-) create mode 100644 src/main/java/space/space_spring/exception/jwt/bad_request/JwtBadRequestException.java create mode 100644 src/main/java/space/space_spring/exception/jwt/bad_request/JwtNoTokenException.java create mode 100644 src/main/java/space/space_spring/exception/jwt/bad_request/JwtUnsupportedTokenException.java create mode 100644 src/main/java/space/space_spring/exception/jwt/unauthorized/JwtExpiredTokenException.java create mode 100644 src/main/java/space/space_spring/exception/jwt/unauthorized/JwtInvalidTokenException.java create mode 100644 src/main/java/space/space_spring/exception/jwt/unauthorized/JwtMalformedTokenException.java create mode 100644 src/main/java/space/space_spring/exception/jwt/unauthorized/JwtUnauthorizedTokenException.java diff --git a/src/main/java/space/space_spring/JwtProvider.java b/src/main/java/space/space_spring/JwtProvider.java index 8de91cdf..bc6e5d38 100644 --- a/src/main/java/space/space_spring/JwtProvider.java +++ b/src/main/java/space/space_spring/JwtProvider.java @@ -1,34 +1,73 @@ package space.space_spring; -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.*; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import space.space_spring.domain.User; +import space.space_spring.exception.jwt.unauthorized.JwtInvalidTokenException; +import space.space_spring.exception.jwt.unauthorized.JwtMalformedTokenException; +import space.space_spring.exception.jwt.bad_request.JwtUnsupportedTokenException; import java.util.Date; +import static space.space_spring.response.status.BaseExceptionResponseStatus.*; + @Component +@Slf4j public class JwtProvider { @Value("${secret.jwt-secret-key}") - private String JWT_TOKEN_KEY; + private String JWT_SECRET_KEY; @Value("${secret.jwt-expired-in}") - private Long JWT_EXPIRATION_TIME; + private Long JWT_EXPIRED_IN; public String generateToken(User user) { Claims claims = Jwts.claims().setSubject(user.getEmail()); Date now = new Date(); - Date expiration = new Date(now.getTime() + JWT_EXPIRATION_TIME); + Date expiration = new Date(now.getTime() + JWT_EXPIRED_IN); return Jwts.builder() .setClaims(claims) .setIssuedAt(now) .setExpiration(expiration) .claim("userId", user.getUserId()) - .signWith(SignatureAlgorithm.HS256, JWT_TOKEN_KEY) + .signWith(SignatureAlgorithm.HS256, JWT_SECRET_KEY) .compact(); } + + public boolean isExpiredToken(String accessToken) { + try { + Jws claims = Jwts.parserBuilder() + .setSigningKey(JWT_SECRET_KEY).build() + .parseClaimsJws(accessToken); + return claims.getBody().getExpiration().before(new Date()); + + } catch (ExpiredJwtException e) { + return true; + + } catch (UnsupportedJwtException e) { + throw new JwtUnsupportedTokenException(UNSUPPORTED_TOKEN_TYPE); + } catch (MalformedJwtException e) { + throw new JwtMalformedTokenException(MALFORMED_TOKEN); + } catch (IllegalArgumentException e) { + throw new JwtInvalidTokenException(INVALID_TOKEN); + } catch (JwtException e) { + log.error("[JwtTokenProvider.validateAccessToken]", e); + throw e; + } + } + + public Long getUserIdFromToken(String accessToken) { + try { + Jws claims = Jwts.parserBuilder() + .setSigningKey(JWT_SECRET_KEY).build() + .parseClaimsJws(accessToken); + return claims.getBody().get("userId", Long.class); + } catch (JwtException e) { + log.error("[JwtTokenProvider.getUserIdFromToken]", e); + throw e; + } + } } diff --git a/src/main/java/space/space_spring/controller/TestController.java b/src/main/java/space/space_spring/controller/TestController.java index d6a7da64..ecb1e51b 100644 --- a/src/main/java/space/space_spring/controller/TestController.java +++ b/src/main/java/space/space_spring/controller/TestController.java @@ -2,6 +2,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; +import space.space_spring.response.BaseResponse; @RestController public class TestController { @@ -10,4 +11,9 @@ public class TestController { public String test(){ return "CI/CD 환경 구축 테스트 중. 이 메세지가 보인다면 성공입니다"; } + + @GetMapping("/test/jwt") + public BaseResponse jwtTest() { + return new BaseResponse<>("jwt test 성공"); + } } diff --git a/src/main/java/space/space_spring/exception/jwt/bad_request/JwtBadRequestException.java b/src/main/java/space/space_spring/exception/jwt/bad_request/JwtBadRequestException.java new file mode 100644 index 00000000..f881a84c --- /dev/null +++ b/src/main/java/space/space_spring/exception/jwt/bad_request/JwtBadRequestException.java @@ -0,0 +1,15 @@ +package space.space_spring.exception.jwt.bad_request; + +import lombok.Getter; +import space.space_spring.response.status.ResponseStatus; + +@Getter +public class JwtBadRequestException extends RuntimeException { + + private final ResponseStatus exceptionStatus; + + public JwtBadRequestException(ResponseStatus exceptionStatus) { + super(exceptionStatus.getMessage()); + this.exceptionStatus = exceptionStatus; + } +} diff --git a/src/main/java/space/space_spring/exception/jwt/bad_request/JwtNoTokenException.java b/src/main/java/space/space_spring/exception/jwt/bad_request/JwtNoTokenException.java new file mode 100644 index 00000000..9b0cdd08 --- /dev/null +++ b/src/main/java/space/space_spring/exception/jwt/bad_request/JwtNoTokenException.java @@ -0,0 +1,16 @@ +package space.space_spring.exception.jwt.bad_request; + +import lombok.Getter; +import space.space_spring.response.status.ResponseStatus; + +@Getter +public class JwtNoTokenException extends JwtBadRequestException { + + private final ResponseStatus exceptionStatus; + + + public JwtNoTokenException(ResponseStatus exceptionStatus) { + super(exceptionStatus); + this.exceptionStatus = exceptionStatus; + } +} diff --git a/src/main/java/space/space_spring/exception/jwt/bad_request/JwtUnsupportedTokenException.java b/src/main/java/space/space_spring/exception/jwt/bad_request/JwtUnsupportedTokenException.java new file mode 100644 index 00000000..a81a9ccc --- /dev/null +++ b/src/main/java/space/space_spring/exception/jwt/bad_request/JwtUnsupportedTokenException.java @@ -0,0 +1,15 @@ +package space.space_spring.exception.jwt.bad_request; + +import lombok.Getter; +import space.space_spring.response.status.ResponseStatus; + +@Getter +public class JwtUnsupportedTokenException extends JwtBadRequestException { + + private final ResponseStatus exceptionStatus; + + public JwtUnsupportedTokenException(ResponseStatus exceptionStatus) { + super(exceptionStatus); + this.exceptionStatus = exceptionStatus; + } +} diff --git a/src/main/java/space/space_spring/exception/jwt/unauthorized/JwtExpiredTokenException.java b/src/main/java/space/space_spring/exception/jwt/unauthorized/JwtExpiredTokenException.java new file mode 100644 index 00000000..3d32ff61 --- /dev/null +++ b/src/main/java/space/space_spring/exception/jwt/unauthorized/JwtExpiredTokenException.java @@ -0,0 +1,16 @@ +package space.space_spring.exception.jwt.unauthorized; + +import lombok.Getter; +import space.space_spring.response.status.ResponseStatus; + +@Getter +public class JwtExpiredTokenException extends JwtUnauthorizedTokenException { + + private final ResponseStatus exceptionStatus; + + public JwtExpiredTokenException(ResponseStatus exceptionStatus) { + super(exceptionStatus); + this.exceptionStatus = exceptionStatus; + } + +} diff --git a/src/main/java/space/space_spring/exception/jwt/unauthorized/JwtInvalidTokenException.java b/src/main/java/space/space_spring/exception/jwt/unauthorized/JwtInvalidTokenException.java new file mode 100644 index 00000000..a7bf33a7 --- /dev/null +++ b/src/main/java/space/space_spring/exception/jwt/unauthorized/JwtInvalidTokenException.java @@ -0,0 +1,15 @@ +package space.space_spring.exception.jwt.unauthorized; + +import lombok.Getter; +import space.space_spring.response.status.ResponseStatus; + +@Getter +public class JwtInvalidTokenException extends JwtUnauthorizedTokenException { + + private final ResponseStatus exceptionStatus; + + public JwtInvalidTokenException(ResponseStatus exceptionStatus) { + super(exceptionStatus); + this.exceptionStatus = exceptionStatus; + } +} diff --git a/src/main/java/space/space_spring/exception/jwt/unauthorized/JwtMalformedTokenException.java b/src/main/java/space/space_spring/exception/jwt/unauthorized/JwtMalformedTokenException.java new file mode 100644 index 00000000..d880970a --- /dev/null +++ b/src/main/java/space/space_spring/exception/jwt/unauthorized/JwtMalformedTokenException.java @@ -0,0 +1,15 @@ +package space.space_spring.exception.jwt.unauthorized; + +import lombok.Getter; +import space.space_spring.response.status.ResponseStatus; + +@Getter +public class JwtMalformedTokenException extends JwtUnauthorizedTokenException { + + private final ResponseStatus exceptionStatus; + + public JwtMalformedTokenException(ResponseStatus exceptionStatus) { + super(exceptionStatus); + this.exceptionStatus = exceptionStatus; + } +} diff --git a/src/main/java/space/space_spring/exception/jwt/unauthorized/JwtUnauthorizedTokenException.java b/src/main/java/space/space_spring/exception/jwt/unauthorized/JwtUnauthorizedTokenException.java new file mode 100644 index 00000000..08326574 --- /dev/null +++ b/src/main/java/space/space_spring/exception/jwt/unauthorized/JwtUnauthorizedTokenException.java @@ -0,0 +1,18 @@ +package space.space_spring.exception.jwt.unauthorized; + +import lombok.Getter; +import space.space_spring.response.status.ResponseStatus; + +@Getter +public class JwtUnauthorizedTokenException extends RuntimeException { + + private final ResponseStatus exceptionStatus; + + public JwtUnauthorizedTokenException(ResponseStatus exceptionStatus) { + super(exceptionStatus.getMessage()); + this.exceptionStatus = exceptionStatus; + } +} + + + diff --git a/src/main/java/space/space_spring/interceptor/JwtAuthInterceptor.java b/src/main/java/space/space_spring/interceptor/JwtAuthInterceptor.java index dc7b76f3..dd1efa50 100644 --- a/src/main/java/space/space_spring/interceptor/JwtAuthInterceptor.java +++ b/src/main/java/space/space_spring/interceptor/JwtAuthInterceptor.java @@ -3,12 +3,15 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; -import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import space.space_spring.JwtProvider; -import space.space_spring.service.UserService; +import space.space_spring.exception.jwt.unauthorized.JwtExpiredTokenException; +import space.space_spring.exception.jwt.bad_request.JwtNoTokenException; +import space.space_spring.exception.jwt.bad_request.JwtUnsupportedTokenException; + +import static space.space_spring.response.status.BaseExceptionResponseStatus.*; @Component @RequiredArgsConstructor @@ -17,11 +20,40 @@ public class JwtAuthInterceptor implements HandlerInterceptor { private static final String JWT_TOKEN_PREFIX = "Bearer "; private final JwtProvider jwtProvider; - private final UserService userService; -// @Override -// public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { -// String accessToken = request.getHeader(HttpHeaders.AUTHORIZATION); -// -// } + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + String accessToken = resolveAccessToken(request); + validateAccessToken(accessToken); + + // jwt에서 userId get + Long userId = jwtProvider.getUserIdFromToken(accessToken); + request.setAttribute("userId", userId); + + return true; + } + + private void validateAccessToken(String accessToken) { + if (jwtProvider.isExpiredToken(accessToken)) { + throw new JwtExpiredTokenException(EXPIRED_TOKEN); + } + + } + + private String resolveAccessToken(HttpServletRequest request) { + String token = request.getHeader(HttpHeaders.AUTHORIZATION); + validateToken(token); + return token.substring(JWT_TOKEN_PREFIX.length()); + } + + private void validateToken(String token) { + if (token == null) { + throw new JwtNoTokenException(TOKEN_NOT_FOUND); + } + if (!token.startsWith(JWT_TOKEN_PREFIX)) { + throw new JwtUnsupportedTokenException(UNSUPPORTED_TOKEN_TYPE); + } + } + + } diff --git a/src/main/java/space/space_spring/service/UserService.java b/src/main/java/space/space_spring/service/UserService.java index 8a330b1d..c6ebbbf2 100644 --- a/src/main/java/space/space_spring/service/UserService.java +++ b/src/main/java/space/space_spring/service/UserService.java @@ -55,7 +55,7 @@ public String login(PostUserLoginRequest postUserLoginRequest) { // TODO 3. JWT 발급 String jwt = jwtProvider.generateToken(userByEmail); - // TODO 4. JWT db에 insert + // TODO 4. JWT db에 insert -> db에 저장해야할까?? userByEmail.saveJWTtoLoginUser(jwt); return jwt; From 50dbbc4d6d57defdfaa179dd0336089e0f3adeb9 Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Mon, 15 Jul 2024 16:43:14 +0900 Subject: [PATCH 05/17] =?UTF-8?q?refactor=20securityConfig=EC=97=90=20?= =?UTF-8?q?=EA=B6=8C=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0=20?= =?UTF-8?q?&=20webConfig=20=EC=BD=94=EB=93=9C=EC=97=90=20=EC=9D=B8?= =?UTF-8?q?=ED=84=B0=EC=85=89=ED=84=B0=20=EB=93=B1=EB=A1=9D=ED=95=A0=20url?= =?UTF-8?q?=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../space_spring/config/SecurityConfig.java | 14 ++++++------ .../space/space_spring/config/WebConfig.java | 22 +++++++++++++++++++ .../interceptor/JwtAuthInterceptor.java | 2 +- .../space_spring/{ => jwt}/JwtProvider.java | 2 +- .../space_spring/service/UserService.java | 3 +-- 5 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 src/main/java/space/space_spring/config/WebConfig.java rename src/main/java/space/space_spring/{ => jwt}/JwtProvider.java (98%) diff --git a/src/main/java/space/space_spring/config/SecurityConfig.java b/src/main/java/space/space_spring/config/SecurityConfig.java index ace7cd44..96713a03 100644 --- a/src/main/java/space/space_spring/config/SecurityConfig.java +++ b/src/main/java/space/space_spring/config/SecurityConfig.java @@ -23,14 +23,14 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti headerConfig.frameOptions(frameOptionsConfig -> frameOptionsConfig.disable() ) - ) - // 요청별 권한 설정 - .authorizeHttpRequests((authorizeRequests) -> - authorizeRequests - .requestMatchers(PathRequest.toH2Console()).permitAll() - .requestMatchers("/", "/user/signup", "/user/login").permitAll() - .anyRequest().authenticated() ); + // 요청별 권한 설정 +// .authorizeHttpRequests((authorizeRequests) -> +// authorizeRequests +// .requestMatchers(PathRequest.toH2Console()).permitAll() +// .requestMatchers("/", "/user/signup", "/user/login").permitAll() +//// .anyRequest().authenticated() +// ); return http.build(); } diff --git a/src/main/java/space/space_spring/config/WebConfig.java b/src/main/java/space/space_spring/config/WebConfig.java new file mode 100644 index 00000000..83fc9aba --- /dev/null +++ b/src/main/java/space/space_spring/config/WebConfig.java @@ -0,0 +1,22 @@ +package space.space_spring.config; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import space.space_spring.interceptor.JwtAuthInterceptor; +import space.space_spring.jwt.JwtProvider; + +@Configuration +@RequiredArgsConstructor +public class WebConfig implements WebMvcConfigurer { + + private final JwtAuthInterceptor jwtAuthInterceptor; + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(jwtAuthInterceptor) + .order(1) + .addPathPatterns("/space/**", "/test/**"); // interceptor 적용되야하는 url enum으로 만들어서 여기에 달면 될듯 + } +} diff --git a/src/main/java/space/space_spring/interceptor/JwtAuthInterceptor.java b/src/main/java/space/space_spring/interceptor/JwtAuthInterceptor.java index dd1efa50..f8728ea3 100644 --- a/src/main/java/space/space_spring/interceptor/JwtAuthInterceptor.java +++ b/src/main/java/space/space_spring/interceptor/JwtAuthInterceptor.java @@ -6,7 +6,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; -import space.space_spring.JwtProvider; +import space.space_spring.jwt.JwtProvider; import space.space_spring.exception.jwt.unauthorized.JwtExpiredTokenException; import space.space_spring.exception.jwt.bad_request.JwtNoTokenException; import space.space_spring.exception.jwt.bad_request.JwtUnsupportedTokenException; diff --git a/src/main/java/space/space_spring/JwtProvider.java b/src/main/java/space/space_spring/jwt/JwtProvider.java similarity index 98% rename from src/main/java/space/space_spring/JwtProvider.java rename to src/main/java/space/space_spring/jwt/JwtProvider.java index bc6e5d38..429a9752 100644 --- a/src/main/java/space/space_spring/JwtProvider.java +++ b/src/main/java/space/space_spring/jwt/JwtProvider.java @@ -1,4 +1,4 @@ -package space.space_spring; +package space.space_spring.jwt; import io.jsonwebtoken.*; import lombok.extern.slf4j.Slf4j; diff --git a/src/main/java/space/space_spring/service/UserService.java b/src/main/java/space/space_spring/service/UserService.java index c6ebbbf2..05863d63 100644 --- a/src/main/java/space/space_spring/service/UserService.java +++ b/src/main/java/space/space_spring/service/UserService.java @@ -3,11 +3,10 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import space.space_spring.JwtProvider; +import space.space_spring.jwt.JwtProvider; import space.space_spring.dao.UserDao; import space.space_spring.domain.User; import space.space_spring.dto.PostUserLoginRequest; -import space.space_spring.dto.PostUserLoginResponse; import space.space_spring.dto.PostUserSignupRequest; import space.space_spring.dto.PostUserSignupResponse; import space.space_spring.exception.UserException; From d5998a49b9514419e36fac2ab2cead1d34457780 Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Mon, 15 Jul 2024 17:54:40 +0900 Subject: [PATCH 06/17] =?UTF-8?q?feat=20jwt=EC=97=90=EC=84=9C=20claim=20?= =?UTF-8?q?=EA=B0=92=20=EC=96=BB=EA=B8=B0=EC=9C=84=ED=95=B4=20argumentReso?= =?UTF-8?q?lver=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JwtAuthHandlerArgumentResolver.java | 26 +++++++++++++++++++ .../argument_resolver/JwtPreAuth.java | 11 ++++++++ .../space/space_spring/config/WebConfig.java | 10 +++++++ 3 files changed, 47 insertions(+) create mode 100644 src/main/java/space/space_spring/argument_resolver/JwtAuthHandlerArgumentResolver.java create mode 100644 src/main/java/space/space_spring/argument_resolver/JwtPreAuth.java diff --git a/src/main/java/space/space_spring/argument_resolver/JwtAuthHandlerArgumentResolver.java b/src/main/java/space/space_spring/argument_resolver/JwtAuthHandlerArgumentResolver.java new file mode 100644 index 00000000..fb6341cb --- /dev/null +++ b/src/main/java/space/space_spring/argument_resolver/JwtAuthHandlerArgumentResolver.java @@ -0,0 +1,26 @@ +package space.space_spring.argument_resolver; + +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +@Component +public class JwtAuthHandlerArgumentResolver implements HandlerMethodArgumentResolver { + + + @Override + public boolean supportsParameter(MethodParameter parameter) { + // 일단 parameter의 return value type 을 검사하지는 X + return parameter.hasParameterAnnotation(JwtPreAuth.class); + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { + HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest(); + return request.getAttribute("userId"); // jwt를 복호화해서 얻은 userId get + } +} diff --git a/src/main/java/space/space_spring/argument_resolver/JwtPreAuth.java b/src/main/java/space/space_spring/argument_resolver/JwtPreAuth.java new file mode 100644 index 00000000..bfd1b19e --- /dev/null +++ b/src/main/java/space/space_spring/argument_resolver/JwtPreAuth.java @@ -0,0 +1,11 @@ +package space.space_spring.argument_resolver; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface JwtPreAuth { +} diff --git a/src/main/java/space/space_spring/config/WebConfig.java b/src/main/java/space/space_spring/config/WebConfig.java index 83fc9aba..03570905 100644 --- a/src/main/java/space/space_spring/config/WebConfig.java +++ b/src/main/java/space/space_spring/config/WebConfig.java @@ -2,16 +2,21 @@ import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import space.space_spring.argument_resolver.JwtAuthHandlerArgumentResolver; import space.space_spring.interceptor.JwtAuthInterceptor; import space.space_spring.jwt.JwtProvider; +import java.util.List; + @Configuration @RequiredArgsConstructor public class WebConfig implements WebMvcConfigurer { private final JwtAuthInterceptor jwtAuthInterceptor; + private final JwtAuthHandlerArgumentResolver authHandlerArgumentResolver; @Override public void addInterceptors(InterceptorRegistry registry) { @@ -19,4 +24,9 @@ public void addInterceptors(InterceptorRegistry registry) { .order(1) .addPathPatterns("/space/**", "/test/**"); // interceptor 적용되야하는 url enum으로 만들어서 여기에 달면 될듯 } + + @Override + public void addArgumentResolvers(List argumentResolvers) { + argumentResolvers.add(authHandlerArgumentResolver); + } } From 5e6ad1c80b1e00850bb90ddfb3e1cfb98242c709 Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Mon, 15 Jul 2024 17:58:05 +0900 Subject: [PATCH 07/17] =?UTF-8?q?Feat=20jwt=EC=97=90=20=EB=84=A3=EC=9D=80?= =?UTF-8?q?=20userId=20=EA=B0=92=20=EC=B6=94=EC=B6=9C=ED=95=98=EA=B8=B0?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20testController=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/space/space_spring/controller/TestController.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/space/space_spring/controller/TestController.java b/src/main/java/space/space_spring/controller/TestController.java index ecb1e51b..b1ca1bdb 100644 --- a/src/main/java/space/space_spring/controller/TestController.java +++ b/src/main/java/space/space_spring/controller/TestController.java @@ -1,10 +1,13 @@ package space.space_spring.controller; +import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; +import space.space_spring.argument_resolver.JwtPreAuth; import space.space_spring.response.BaseResponse; @RestController +@Slf4j public class TestController { @GetMapping("/test") @@ -13,7 +16,8 @@ public String test(){ } @GetMapping("/test/jwt") - public BaseResponse jwtTest() { + public BaseResponse jwtTest(@JwtPreAuth Long userId) { + log.info("userId = {}", userId); return new BaseResponse<>("jwt test 성공"); } } From e375c029afd0f43bc85765329646c1245778ae5b Mon Sep 17 00:00:00 2001 From: kim_sang_ june <79149384+drbug2000@users.noreply.github.com> Date: Mon, 15 Jul 2024 18:16:58 +0900 Subject: [PATCH 08/17] [chore] gitignore application-local add gitignore "applicaion-local.yml" --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index c2065bc2..bbbc10b5 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,7 @@ out/ ### VS Code ### .vscode/ + +### application-local.yml ### +src/main/resource/application-local.yml +/**/application-local.yml \ No newline at end of file From b51007c9be35fcf9e5b50e61390186ffc1842533 Mon Sep 17 00:00:00 2001 From: kim_sang_ june <79149384+drbug2000@users.noreply.github.com> Date: Mon, 15 Jul 2024 19:17:13 +0900 Subject: [PATCH 09/17] [chore] update application.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit local-dev-prod 분리 DB, jpa, secret 설정 --- src/main/resources/application.yml | 77 +++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 7 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 52fc80a1..58c98f82 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,26 +1,89 @@ +spring: + profiles: + active: ${SPRING_PROFILES_ACTIVE:dev} + group: + "local": "localRDB, localMongoDB, localJPA, localPort, localSecret, web-mvc" + "dev": "devRDB, devMongoDB, devPort, devJPA, devSecret, web-mvc" + "prod": "devRDB, devMongoDB, devPort, prodJPA, devSecret, web-mvc" +--- +spring: + config: + activate: + on-profile: "devPort" server: port: 8080 - +--- spring: + config: + activate: + on-profile: "devRDB" + datasource: url: ${DATASOURCE_URL_LOCAL} username: ${DATASOURCE_USERNAME} password: ${DATASOURCE_PASSWORD} - driver-class-name: ${DATASOURCE_DRIVER} + driver-class-name: com.mysql.cj.jdbc.Driver +logging: + level: + org.hibernate.sql: debug +--- +spring: + config: + activate: + on-profile: "devMongoDB" + data: + mongodb: + uri: mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOST}:${MONGO_PORT}/${MONGO_DB} + +--- +spring: + config: + activate: + on-profile: "devJPA" jpa: hibernate: - ddl-auto: update # table을 전부 drop했다가 다시 생성 -> 테스트용 + ddl-auto: validate properties: hibernate: format_sql: true show_sql: true +--- +spring: + config: + activate: + on-profile: "prodJPA" + + jpa: + hibernate: + ddl-auto: none + properties: + hibernate: + show_sql: false +--- +spring: + config: + activate: + on-profile: "devSecret" secret: jwt-secret-key: ${JWT_SECRET_KEY} - jwt-expired-in: ${JWT_EXPIRED_IN} + jwt-expired-in: ${JWT_EXPIRED_IN:3600000} +--- + +spring: + config: + activate: + on-profile: "web-mvc" + + mvc: + throw-exception-if-no-handler-found: true + + web: + resources: + add-mappings: false + + messages: + basename: errors -logging: - level: - org.hibernate.sql: debug From d0b49bba310c1b5cbca44fd6cc671a75c9b9bb5e Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Tue, 16 Jul 2024 10:24:39 +0900 Subject: [PATCH 10/17] =?UTF-8?q?Feat=20space=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=EC=9D=84=20=EC=9C=84=ED=95=9C=20controller,?= =?UTF-8?q?=20exception,=20dto,=20service,=20dao=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/SpaceController.java | 35 +++++++++++++++++++ .../controller/UserController.java | 14 ++++---- .../java/space/space_spring/dao/SpaceDao.java | 9 +++++ .../java/space/space_spring/dao/UserDao.java | 2 +- .../dto/space/PostSpaceCreateRequest.java | 17 +++++++++ .../dto/space/PostSpaceCreateResponse.java | 11 ++++++ .../dto/{ => user}/PostUserLoginRequest.java | 2 +- .../dto/{ => user}/PostUserLoginResponse.java | 2 +- .../dto/{ => user}/PostUserSignupRequest.java | 2 +- .../{ => user}/PostUserSignupResponse.java | 2 +- .../exception/SpaceException.java | 21 +++++++++++ .../status/BaseExceptionResponseStatus.java | 28 +++++++++++++-- .../space_spring/service/SpaceService.java | 19 ++++++++++ .../space_spring/service/UserService.java | 6 ++-- .../space_spring/service/UserServiceTest.java | 10 ------ 15 files changed, 153 insertions(+), 27 deletions(-) create mode 100644 src/main/java/space/space_spring/controller/SpaceController.java create mode 100644 src/main/java/space/space_spring/dao/SpaceDao.java create mode 100644 src/main/java/space/space_spring/dto/space/PostSpaceCreateRequest.java create mode 100644 src/main/java/space/space_spring/dto/space/PostSpaceCreateResponse.java rename src/main/java/space/space_spring/dto/{ => user}/PostUserLoginRequest.java (94%) rename src/main/java/space/space_spring/dto/{ => user}/PostUserLoginResponse.java (80%) rename src/main/java/space/space_spring/dto/{ => user}/PostUserSignupRequest.java (96%) rename src/main/java/space/space_spring/dto/{ => user}/PostUserSignupResponse.java (85%) create mode 100644 src/main/java/space/space_spring/exception/SpaceException.java create mode 100644 src/main/java/space/space_spring/service/SpaceService.java diff --git a/src/main/java/space/space_spring/controller/SpaceController.java b/src/main/java/space/space_spring/controller/SpaceController.java new file mode 100644 index 00000000..22fec97c --- /dev/null +++ b/src/main/java/space/space_spring/controller/SpaceController.java @@ -0,0 +1,35 @@ +package space.space_spring.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import space.space_spring.argument_resolver.JwtPreAuth; +import space.space_spring.dto.space.PostSpaceCreateRequest; +import space.space_spring.dto.space.PostSpaceCreateResponse; + +import space.space_spring.exception.SpaceException; +import space.space_spring.response.BaseResponse; +import space.space_spring.service.SpaceService; + +import static space.space_spring.response.status.BaseExceptionResponseStatus.INVALID_SPACE_CREATE; +import static space.space_spring.util.BindingResultUtils.getErrorMessage; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/space") +public class SpaceController { + + private final SpaceService spaceService; + + @PostMapping("/create") + public BaseResponse createSpace(@JwtPreAuth Long userId, PostSpaceCreateRequest postSpaceCreateRequest, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + throw new SpaceException(INVALID_SPACE_CREATE, getErrorMessage(bindingResult)); + } + + return new BaseResponse<>(spaceService.createSpace(userId, postSpaceCreateRequest)); + } + +} diff --git a/src/main/java/space/space_spring/controller/UserController.java b/src/main/java/space/space_spring/controller/UserController.java index 77ee6464..2f066e48 100644 --- a/src/main/java/space/space_spring/controller/UserController.java +++ b/src/main/java/space/space_spring/controller/UserController.java @@ -9,15 +9,15 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import space.space_spring.dto.PostUserLoginRequest; -import space.space_spring.dto.PostUserLoginResponse; -import space.space_spring.dto.PostUserSignupRequest; -import space.space_spring.dto.PostUserSignupResponse; +import space.space_spring.dto.user.PostUserLoginRequest; +import space.space_spring.dto.user.PostUserLoginResponse; +import space.space_spring.dto.user.PostUserSignupRequest; +import space.space_spring.dto.user.PostUserSignupResponse; import space.space_spring.exception.UserException; import space.space_spring.response.BaseResponse; import space.space_spring.service.UserService; -import static space.space_spring.response.status.BaseExceptionResponseStatus.INVALID_USER_VALUE; +import static space.space_spring.response.status.BaseExceptionResponseStatus.*; import static space.space_spring.util.BindingResultUtils.getErrorMessage; @Slf4j @@ -34,7 +34,7 @@ public class UserController { @PostMapping("/signup") public BaseResponse signup(@Validated @RequestBody PostUserSignupRequest postUserSignupRequest, BindingResult bindingResult) { if (bindingResult.hasErrors()) { - throw new UserException(INVALID_USER_VALUE, getErrorMessage(bindingResult)); + throw new UserException(INVALID_USER_SIGNUP, getErrorMessage(bindingResult)); } return new BaseResponse<>(userService.signup(postUserSignupRequest)); } @@ -45,7 +45,7 @@ public BaseResponse signup(@Validated @RequestBody PostU @PostMapping("/login") public BaseResponse login(@Validated @RequestBody PostUserLoginRequest postUserLoginRequest, BindingResult bindingResult, HttpServletResponse response) { if (bindingResult.hasErrors()) { - throw new UserException(INVALID_USER_VALUE, getErrorMessage(bindingResult)); + throw new UserException(INVALID_USER_LOGIN, getErrorMessage(bindingResult)); } String jwt = userService.login(postUserLoginRequest); diff --git a/src/main/java/space/space_spring/dao/SpaceDao.java b/src/main/java/space/space_spring/dao/SpaceDao.java new file mode 100644 index 00000000..11ed03e5 --- /dev/null +++ b/src/main/java/space/space_spring/dao/SpaceDao.java @@ -0,0 +1,9 @@ +package space.space_spring.dao; + +import org.springframework.stereotype.Repository; + +@Repository +public class SpaceDao { + + +} diff --git a/src/main/java/space/space_spring/dao/UserDao.java b/src/main/java/space/space_spring/dao/UserDao.java index 7c5a3e11..4a363401 100644 --- a/src/main/java/space/space_spring/dao/UserDao.java +++ b/src/main/java/space/space_spring/dao/UserDao.java @@ -6,7 +6,7 @@ import jakarta.persistence.TypedQuery; import org.springframework.stereotype.Repository; import space.space_spring.domain.User; -import space.space_spring.dto.PostUserSignupRequest; +import space.space_spring.dto.user.PostUserSignupRequest; @Repository public class UserDao { diff --git a/src/main/java/space/space_spring/dto/space/PostSpaceCreateRequest.java b/src/main/java/space/space_spring/dto/space/PostSpaceCreateRequest.java new file mode 100644 index 00000000..918727f5 --- /dev/null +++ b/src/main/java/space/space_spring/dto/space/PostSpaceCreateRequest.java @@ -0,0 +1,17 @@ +package space.space_spring.dto.space; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.hibernate.validator.constraints.Length; + +@Getter +@Setter +@NoArgsConstructor +public class PostSpaceCreateRequest { + + @Length(min = 1, max = 10, message = "이름은 10자이내의 문자열이어야 합니다.") + private String spaceName; + + private String spaceProfileImg; // 스페이스 프로필 이미지 (썸네일) +} diff --git a/src/main/java/space/space_spring/dto/space/PostSpaceCreateResponse.java b/src/main/java/space/space_spring/dto/space/PostSpaceCreateResponse.java new file mode 100644 index 00000000..26479f54 --- /dev/null +++ b/src/main/java/space/space_spring/dto/space/PostSpaceCreateResponse.java @@ -0,0 +1,11 @@ +package space.space_spring.dto.space; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class PostSpaceCreateResponse { + + private Long spaceId; +} diff --git a/src/main/java/space/space_spring/dto/PostUserLoginRequest.java b/src/main/java/space/space_spring/dto/user/PostUserLoginRequest.java similarity index 94% rename from src/main/java/space/space_spring/dto/PostUserLoginRequest.java rename to src/main/java/space/space_spring/dto/user/PostUserLoginRequest.java index 5393b72f..55c98254 100644 --- a/src/main/java/space/space_spring/dto/PostUserLoginRequest.java +++ b/src/main/java/space/space_spring/dto/user/PostUserLoginRequest.java @@ -1,4 +1,4 @@ -package space.space_spring.dto; +package space.space_spring.dto.user; import jakarta.validation.constraints.Pattern; import lombok.Getter; diff --git a/src/main/java/space/space_spring/dto/PostUserLoginResponse.java b/src/main/java/space/space_spring/dto/user/PostUserLoginResponse.java similarity index 80% rename from src/main/java/space/space_spring/dto/PostUserLoginResponse.java rename to src/main/java/space/space_spring/dto/user/PostUserLoginResponse.java index 14aa5a5f..29b631c5 100644 --- a/src/main/java/space/space_spring/dto/PostUserLoginResponse.java +++ b/src/main/java/space/space_spring/dto/user/PostUserLoginResponse.java @@ -1,4 +1,4 @@ -package space.space_spring.dto; +package space.space_spring.dto.user; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/src/main/java/space/space_spring/dto/PostUserSignupRequest.java b/src/main/java/space/space_spring/dto/user/PostUserSignupRequest.java similarity index 96% rename from src/main/java/space/space_spring/dto/PostUserSignupRequest.java rename to src/main/java/space/space_spring/dto/user/PostUserSignupRequest.java index 0172461c..170234c6 100644 --- a/src/main/java/space/space_spring/dto/PostUserSignupRequest.java +++ b/src/main/java/space/space_spring/dto/user/PostUserSignupRequest.java @@ -1,4 +1,4 @@ -package space.space_spring.dto; +package space.space_spring.dto.user; import jakarta.validation.constraints.Pattern; import lombok.AllArgsConstructor; diff --git a/src/main/java/space/space_spring/dto/PostUserSignupResponse.java b/src/main/java/space/space_spring/dto/user/PostUserSignupResponse.java similarity index 85% rename from src/main/java/space/space_spring/dto/PostUserSignupResponse.java rename to src/main/java/space/space_spring/dto/user/PostUserSignupResponse.java index 4dd0056b..3fb00679 100644 --- a/src/main/java/space/space_spring/dto/PostUserSignupResponse.java +++ b/src/main/java/space/space_spring/dto/user/PostUserSignupResponse.java @@ -1,4 +1,4 @@ -package space.space_spring.dto; +package space.space_spring.dto.user; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/src/main/java/space/space_spring/exception/SpaceException.java b/src/main/java/space/space_spring/exception/SpaceException.java new file mode 100644 index 00000000..d8369c8f --- /dev/null +++ b/src/main/java/space/space_spring/exception/SpaceException.java @@ -0,0 +1,21 @@ +package space.space_spring.exception; + +import lombok.Getter; +import space.space_spring.response.status.ResponseStatus; + +@Getter +public class SpaceException extends RuntimeException { + + private final ResponseStatus exceptionStatus; + + public SpaceException(ResponseStatus exceptionStatus) { + super(exceptionStatus.getMessage()); + this.exceptionStatus = exceptionStatus; + } + + public SpaceException(ResponseStatus exceptionStatus, String message) { + super(message); + this.exceptionStatus = exceptionStatus; + } + +} diff --git a/src/main/java/space/space_spring/response/status/BaseExceptionResponseStatus.java b/src/main/java/space/space_spring/response/status/BaseExceptionResponseStatus.java index 1a5c7410..f92ef72b 100644 --- a/src/main/java/space/space_spring/response/status/BaseExceptionResponseStatus.java +++ b/src/main/java/space/space_spring/response/status/BaseExceptionResponseStatus.java @@ -40,13 +40,37 @@ public enum BaseExceptionResponseStatus implements ResponseStatus { /** * 5000: User 오류 */ - INVALID_USER_VALUE(5000, HttpStatus.BAD_REQUEST.value(), "회원가입 요청에서 잘못된 값이 존재합니다."), + INVALID_USER_SIGNUP(5000, HttpStatus.BAD_REQUEST.value(), "회원가입 요청에서 잘못된 값이 존재합니다."), DUPLICATE_EMAIL(5001, HttpStatus.BAD_REQUEST.value(), "이미 존재하는 이메일입니다."), DUPLICATE_NICKNAME(5002, HttpStatus.BAD_REQUEST.value(), "이미 존재하는 닉네임입니다."), USER_NOT_FOUND(4003, HttpStatus.BAD_REQUEST.value(), "존재하지 않는 회원입니다."), PASSWORD_NO_MATCH(4004, HttpStatus.BAD_REQUEST.value(), "비밀번호가 일치하지 않습니다."), INVALID_USER_STATUS(4005, HttpStatus.BAD_REQUEST.value(), "잘못된 회원 status 값입니다."), - EMAIL_NOT_FOUND(4006, HttpStatus.BAD_REQUEST.value(), "존재하지 않는 이메일입니다."); + EMAIL_NOT_FOUND(4006, HttpStatus.BAD_REQUEST.value(), "존재하지 않는 이메일입니다."), + INVALID_USER_LOGIN(4007, HttpStatus.BAD_REQUEST.value(), "로그인 요청에서 잘못된 값이 존재합니다."), + + /** + * 6000: Space 오류 + */ + INVALID_SPACE_CREATE(6000, HttpStatus.BAD_REQUEST.value(), "스페이스 생성 요청에서 잘못된 값이 존재합니다."), + safd(6001, HttpStatus.BAD_REQUEST.value(), "이미 존재하는 이메일입니다."), + adff(6002, HttpStatus.BAD_REQUEST.value(), "이미 존재하는 닉네임입니다."), + baab(6003, HttpStatus.BAD_REQUEST.value(), "존재하지 않는 회원입니다."), + nff(6004, HttpStatus.BAD_REQUEST.value(), "비밀번호가 일치하지 않습니다."), + gnf(6005, HttpStatus.BAD_REQUEST.value(), "잘못된 회원 status 값입니다."), + fb(6006, HttpStatus.BAD_REQUEST.value(), "존재하지 않는 이메일입니다."), + + + /** + * 7000: 오류 + */ + A(7000, HttpStatus.BAD_REQUEST.value(), "회원가입 요청에서 잘못된 값이 존재합니다."), + B(7001, HttpStatus.BAD_REQUEST.value(), "이미 존재하는 이메일입니다."), + C(7002, HttpStatus.BAD_REQUEST.value(), "이미 존재하는 닉네임입니다."), + D(7003, HttpStatus.BAD_REQUEST.value(), "존재하지 않는 회원입니다."), + E(7004, HttpStatus.BAD_REQUEST.value(), "비밀번호가 일치하지 않습니다."), + F(7005, HttpStatus.BAD_REQUEST.value(), "잘못된 회원 status 값입니다."), + G(7006, HttpStatus.BAD_REQUEST.value(), "존재하지 않는 이메일입니다."); private final int code; private final int status; diff --git a/src/main/java/space/space_spring/service/SpaceService.java b/src/main/java/space/space_spring/service/SpaceService.java new file mode 100644 index 00000000..47a8b1ea --- /dev/null +++ b/src/main/java/space/space_spring/service/SpaceService.java @@ -0,0 +1,19 @@ +package space.space_spring.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import space.space_spring.dao.SpaceDao; +import space.space_spring.dto.space.PostSpaceCreateRequest; +import space.space_spring.dto.space.PostSpaceCreateResponse; + +@Service +@RequiredArgsConstructor +public class SpaceService { + + private final SpaceDao spaceDao; + + public PostSpaceCreateResponse createSpace(Long userId, PostSpaceCreateRequest postSpaceCreateRequest) { + + + } +} diff --git a/src/main/java/space/space_spring/service/UserService.java b/src/main/java/space/space_spring/service/UserService.java index 05863d63..eb3e79dc 100644 --- a/src/main/java/space/space_spring/service/UserService.java +++ b/src/main/java/space/space_spring/service/UserService.java @@ -6,9 +6,9 @@ import space.space_spring.jwt.JwtProvider; import space.space_spring.dao.UserDao; import space.space_spring.domain.User; -import space.space_spring.dto.PostUserLoginRequest; -import space.space_spring.dto.PostUserSignupRequest; -import space.space_spring.dto.PostUserSignupResponse; +import space.space_spring.dto.user.PostUserLoginRequest; +import space.space_spring.dto.user.PostUserSignupRequest; +import space.space_spring.dto.user.PostUserSignupResponse; import space.space_spring.exception.UserException; import static space.space_spring.response.status.BaseExceptionResponseStatus.*; diff --git a/src/test/java/space/space_spring/service/UserServiceTest.java b/src/test/java/space/space_spring/service/UserServiceTest.java index c4d8df07..d0a19710 100644 --- a/src/test/java/space/space_spring/service/UserServiceTest.java +++ b/src/test/java/space/space_spring/service/UserServiceTest.java @@ -1,16 +1,6 @@ package space.space_spring.service; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.annotation.Rollback; -import org.springframework.transaction.annotation.Transactional; -import space.space_spring.dao.UserDao; -import space.space_spring.domain.User; -import space.space_spring.dto.PostUserSignupRequest; -import space.space_spring.dto.PostUserSignupResponse; @SpringBootTest class UserServiceTest { From 22443ca24d2e6b117c9c96d47878cf72004773cd Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Tue, 16 Jul 2024 11:10:55 +0900 Subject: [PATCH 11/17] =?UTF-8?q?Feat=20=EC=8A=A4=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=20=EC=83=9D=EC=84=B1=EC=A0=95=EB=B3=B4=20db=EC=97=90?= =?UTF-8?q?=20insert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/space/space_spring/dao/SpaceDao.java | 13 +++++++++++++ src/main/java/space/space_spring/domain/Space.java | 7 +++++++ .../java/space/space_spring/domain/UserSpace.java | 4 ++++ .../space/space_spring/service/SpaceService.java | 8 ++++++++ 4 files changed, 32 insertions(+) diff --git a/src/main/java/space/space_spring/dao/SpaceDao.java b/src/main/java/space/space_spring/dao/SpaceDao.java index 11ed03e5..9e4dfdec 100644 --- a/src/main/java/space/space_spring/dao/SpaceDao.java +++ b/src/main/java/space/space_spring/dao/SpaceDao.java @@ -1,9 +1,22 @@ package space.space_spring.dao; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; import org.springframework.stereotype.Repository; +import space.space_spring.domain.Space; +import space.space_spring.dto.space.PostSpaceCreateRequest; @Repository public class SpaceDao { + @PersistenceContext + private EntityManager em; + public Long saveSpace(PostSpaceCreateRequest postSpaceCreateRequest) { + Space space = new Space(); + space.saveSpace(postSpaceCreateRequest.getSpaceName(), postSpaceCreateRequest.getSpaceProfileImg()); + + em.persist(space); + return space.getSpaceId(); + } } diff --git a/src/main/java/space/space_spring/domain/Space.java b/src/main/java/space/space_spring/domain/Space.java index 0a5c5ea0..bc9c38e0 100644 --- a/src/main/java/space/space_spring/domain/Space.java +++ b/src/main/java/space/space_spring/domain/Space.java @@ -19,4 +19,11 @@ public class Space extends BaseEntity { @Column(name = "space_profile_img") @Nullable private String spaceProfileImg; + + public void saveSpace(String spaceName, String spaceProfileImg) { + this.spaceName = spaceName; + this.spaceProfileImg = spaceProfileImg; + initializeBaseEntityFields(); + } + } diff --git a/src/main/java/space/space_spring/domain/UserSpace.java b/src/main/java/space/space_spring/domain/UserSpace.java index 5d44ee9b..66098376 100644 --- a/src/main/java/space/space_spring/domain/UserSpace.java +++ b/src/main/java/space/space_spring/domain/UserSpace.java @@ -32,11 +32,15 @@ public class UserSpace extends BaseEntity { @Nullable private String userProfileMsg; + // 스페이스의 관리자 vs 일반 멤버 @Column(name = "user_auth") private String userAuth; + // 스페이스 선택화면에서의 배치 순서 @Column(name = "space_order") private int spaceOrder; + + } diff --git a/src/main/java/space/space_spring/service/SpaceService.java b/src/main/java/space/space_spring/service/SpaceService.java index 47a8b1ea..fc708420 100644 --- a/src/main/java/space/space_spring/service/SpaceService.java +++ b/src/main/java/space/space_spring/service/SpaceService.java @@ -14,6 +14,14 @@ public class SpaceService { public PostSpaceCreateResponse createSpace(Long userId, PostSpaceCreateRequest postSpaceCreateRequest) { + // TODO 1. 스페이스 생성 정보 db insert + Long spaceId = spaceDao.saveSpace(postSpaceCreateRequest); + // TODO 2. 유저_스페이스 매핑 정보 db insert + + + // TODO 3. jwt에 space 정보 추가 + + return new PostSpaceCreateResponse(spaceId); } } From ae030ec4d3dfe530cb71d12831c864b288be4c73 Mon Sep 17 00:00:00 2001 From: kim_sang_ june <79149384+drbug2000@users.noreply.github.com> Date: Tue, 16 Jul 2024 11:29:32 +0900 Subject: [PATCH 12/17] [chore] update cicd condition develop branch only process CI main branch process CI & CD --- .github/workflows/gradle.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 5a8be3ac..e38ccf5c 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -9,9 +9,13 @@ name: CI/CD gradle on: push: - branches: [ "main" ] + branches: + - "main" + - "develop" pull_request: - branches: [ "main" ] + branches: + - "main" + - "develop" env: AWS_REGION: ap-northeast-2 @@ -62,6 +66,7 @@ jobs: name: deploy runs-on: ubuntu-latest needs: build + if: github.ref == 'refs/heads/main' environment: production steps: # (1) 기본 체크아웃 From 4855761e15425540df3d79944bd0ae5f22b66c4a Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Tue, 16 Jul 2024 14:27:48 +0900 Subject: [PATCH 13/17] =?UTF-8?q?Feat=20=EC=8A=A4=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=20=EC=83=9D=EC=84=B1=20&=20=EC=8A=A4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4-=EC=9C=A0=EC=A0=80=20=EB=A7=A4=ED=95=91=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20insert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/SpaceController.java | 4 +++- .../java/space/space_spring/dao/SpaceDao.java | 17 ++++++++++++++--- .../java/space/space_spring/dao/UserDao.java | 12 +++++++++--- .../dto/space/PostSpaceCreateRequest.java | 3 +++ .../dto/user/PostUserLoginRequest.java | 3 +++ .../dto/user/PostUserSignupRequest.java | 4 ++++ .../{domain => entity}/BaseEntity.java | 2 +- .../space_spring/{domain => entity}/Space.java | 4 +--- .../space_spring/{domain => entity}/User.java | 5 +---- .../{domain => entity}/UserSpace.java | 12 +++++++++--- .../entity/enumStatus/UserSpaceAuth.java | 15 +++++++++++++++ .../space/space_spring/jwt/JwtProvider.java | 2 +- .../space_spring/service/SpaceService.java | 14 +++++++++++--- .../space/space_spring/service/UserService.java | 6 +++--- 14 files changed, 78 insertions(+), 25 deletions(-) rename src/main/java/space/space_spring/{domain => entity}/BaseEntity.java (95%) rename src/main/java/space/space_spring/{domain => entity}/Space.java (86%) rename src/main/java/space/space_spring/{domain => entity}/User.java (81%) rename src/main/java/space/space_spring/{domain => entity}/UserSpace.java (70%) create mode 100644 src/main/java/space/space_spring/entity/enumStatus/UserSpaceAuth.java diff --git a/src/main/java/space/space_spring/controller/SpaceController.java b/src/main/java/space/space_spring/controller/SpaceController.java index 22fec97c..6d5dac81 100644 --- a/src/main/java/space/space_spring/controller/SpaceController.java +++ b/src/main/java/space/space_spring/controller/SpaceController.java @@ -2,7 +2,9 @@ import lombok.RequiredArgsConstructor; import org.springframework.validation.BindingResult; +import org.springframework.validation.annotation.Validated; 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.RestController; import space.space_spring.argument_resolver.JwtPreAuth; @@ -24,7 +26,7 @@ public class SpaceController { private final SpaceService spaceService; @PostMapping("/create") - public BaseResponse createSpace(@JwtPreAuth Long userId, PostSpaceCreateRequest postSpaceCreateRequest, BindingResult bindingResult) { + public BaseResponse createSpace(@JwtPreAuth Long userId, @Validated @RequestBody PostSpaceCreateRequest postSpaceCreateRequest, BindingResult bindingResult) { if (bindingResult.hasErrors()) { throw new SpaceException(INVALID_SPACE_CREATE, getErrorMessage(bindingResult)); } diff --git a/src/main/java/space/space_spring/dao/SpaceDao.java b/src/main/java/space/space_spring/dao/SpaceDao.java index 9e4dfdec..f1fb8be3 100644 --- a/src/main/java/space/space_spring/dao/SpaceDao.java +++ b/src/main/java/space/space_spring/dao/SpaceDao.java @@ -3,20 +3,31 @@ import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import org.springframework.stereotype.Repository; -import space.space_spring.domain.Space; +import space.space_spring.entity.Space; +import space.space_spring.entity.User; +import space.space_spring.entity.UserSpace; import space.space_spring.dto.space.PostSpaceCreateRequest; +import static space.space_spring.entity.enumStatus.UserSpaceAuth.MANAGER; + @Repository public class SpaceDao { @PersistenceContext private EntityManager em; - public Long saveSpace(PostSpaceCreateRequest postSpaceCreateRequest) { + public Space saveSpace(PostSpaceCreateRequest postSpaceCreateRequest) { Space space = new Space(); space.saveSpace(postSpaceCreateRequest.getSpaceName(), postSpaceCreateRequest.getSpaceProfileImg()); em.persist(space); - return space.getSpaceId(); + return space; + } + + public void createUserSpace(User manager, Space saveSpace) { + UserSpace userSpace = new UserSpace(); + userSpace.createUserSpace(manager, saveSpace, MANAGER); + + em.persist(userSpace); } } diff --git a/src/main/java/space/space_spring/dao/UserDao.java b/src/main/java/space/space_spring/dao/UserDao.java index 4a363401..70caafc9 100644 --- a/src/main/java/space/space_spring/dao/UserDao.java +++ b/src/main/java/space/space_spring/dao/UserDao.java @@ -5,7 +5,7 @@ import jakarta.persistence.PersistenceContext; import jakarta.persistence.TypedQuery; import org.springframework.stereotype.Repository; -import space.space_spring.domain.User; +import space.space_spring.entity.User; import space.space_spring.dto.user.PostUserSignupRequest; @Repository @@ -14,12 +14,12 @@ public class UserDao { @PersistenceContext private EntityManager em; - public Long saveUser(PostUserSignupRequest postUserSignupRequest) { + public User saveUser(PostUserSignupRequest postUserSignupRequest) { User user = new User(); user.saveUser(postUserSignupRequest.getEmail(), postUserSignupRequest.getPassword(), postUserSignupRequest.getUserName()); em.persist(user); - return user.getUserId(); + return user; } public User findUserByEmail(String email) { @@ -43,4 +43,10 @@ public User getUserByEmail(String email) { return null; } } + + public User findUserByUserId(Long userId) { + TypedQuery query = em.createQuery("SELECT u FROM User u WHERE u.userId = :userId", User.class); + query.setParameter("userId", userId); + return query.getSingleResult(); + } } diff --git a/src/main/java/space/space_spring/dto/space/PostSpaceCreateRequest.java b/src/main/java/space/space_spring/dto/space/PostSpaceCreateRequest.java index 918727f5..e92eafa7 100644 --- a/src/main/java/space/space_spring/dto/space/PostSpaceCreateRequest.java +++ b/src/main/java/space/space_spring/dto/space/PostSpaceCreateRequest.java @@ -1,5 +1,6 @@ package space.space_spring.dto.space; +import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -11,7 +12,9 @@ public class PostSpaceCreateRequest { @Length(min = 1, max = 10, message = "이름은 10자이내의 문자열이어야 합니다.") + @NotBlank(message = "스페이스 이름은 공백일 수 없습니다.") private String spaceName; + @NotBlank(message = "스페이스 프로필 이미지는 공백일 수 없습니다.") private String spaceProfileImg; // 스페이스 프로필 이미지 (썸네일) } diff --git a/src/main/java/space/space_spring/dto/user/PostUserLoginRequest.java b/src/main/java/space/space_spring/dto/user/PostUserLoginRequest.java index 55c98254..69f8768f 100644 --- a/src/main/java/space/space_spring/dto/user/PostUserLoginRequest.java +++ b/src/main/java/space/space_spring/dto/user/PostUserLoginRequest.java @@ -1,5 +1,6 @@ package space.space_spring.dto.user; +import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Pattern; import lombok.Getter; import lombok.NoArgsConstructor; @@ -11,11 +12,13 @@ public class PostUserLoginRequest { @Pattern(regexp = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,6}$", message = "이메일 형식에 맞지 않습니다.") // 이메일 정규표현식 확인 필요함 + @NotBlank private String email; @Pattern( regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,16}$", message = "8~16글자의 영문 대/소문자, 숫자, 특수문자가 포함되어야 합니다." ) + @NotBlank private String password; } diff --git a/src/main/java/space/space_spring/dto/user/PostUserSignupRequest.java b/src/main/java/space/space_spring/dto/user/PostUserSignupRequest.java index 170234c6..c483849d 100644 --- a/src/main/java/space/space_spring/dto/user/PostUserSignupRequest.java +++ b/src/main/java/space/space_spring/dto/user/PostUserSignupRequest.java @@ -1,5 +1,6 @@ package space.space_spring.dto.user; +import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Pattern; import lombok.AllArgsConstructor; import lombok.Getter; @@ -14,14 +15,17 @@ public class PostUserSignupRequest { @Pattern(regexp = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,6}$", message = "이메일 형식에 맞지 않습니다.") // 이메일 정규표현식 확인 필요함 + @NotBlank private String email; @Pattern( regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,16}$", message = "8~16글자의 영문 대/소문자, 숫자, 특수문자가 포함되어야 합니다." ) + @NotBlank private String password; @Length(min = 1, max = 10, message = "이름은 10자이내의 문자열이어야 합니다.") + @NotBlank private String userName; } diff --git a/src/main/java/space/space_spring/domain/BaseEntity.java b/src/main/java/space/space_spring/entity/BaseEntity.java similarity index 95% rename from src/main/java/space/space_spring/domain/BaseEntity.java rename to src/main/java/space/space_spring/entity/BaseEntity.java index ff7f133c..4b035dd0 100644 --- a/src/main/java/space/space_spring/domain/BaseEntity.java +++ b/src/main/java/space/space_spring/entity/BaseEntity.java @@ -1,4 +1,4 @@ -package space.space_spring.domain; +package space.space_spring.entity; import jakarta.persistence.*; diff --git a/src/main/java/space/space_spring/domain/Space.java b/src/main/java/space/space_spring/entity/Space.java similarity index 86% rename from src/main/java/space/space_spring/domain/Space.java rename to src/main/java/space/space_spring/entity/Space.java index bc9c38e0..a07a3b6c 100644 --- a/src/main/java/space/space_spring/domain/Space.java +++ b/src/main/java/space/space_spring/entity/Space.java @@ -1,6 +1,5 @@ -package space.space_spring.domain; +package space.space_spring.entity; -import jakarta.annotation.Nullable; import jakarta.persistence.*; import lombok.Getter; @@ -17,7 +16,6 @@ public class Space extends BaseEntity { private String spaceName; @Column(name = "space_profile_img") - @Nullable private String spaceProfileImg; public void saveSpace(String spaceName, String spaceProfileImg) { diff --git a/src/main/java/space/space_spring/domain/User.java b/src/main/java/space/space_spring/entity/User.java similarity index 81% rename from src/main/java/space/space_spring/domain/User.java rename to src/main/java/space/space_spring/entity/User.java index b15bc936..a13a9430 100644 --- a/src/main/java/space/space_spring/domain/User.java +++ b/src/main/java/space/space_spring/entity/User.java @@ -1,11 +1,8 @@ -package space.space_spring.domain; +package space.space_spring.entity; import jakarta.annotation.Nullable; import jakarta.persistence.*; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.Pattern; import lombok.Getter; -import org.hibernate.validator.constraints.Length; @Entity @Table(name = "Users") diff --git a/src/main/java/space/space_spring/domain/UserSpace.java b/src/main/java/space/space_spring/entity/UserSpace.java similarity index 70% rename from src/main/java/space/space_spring/domain/UserSpace.java rename to src/main/java/space/space_spring/entity/UserSpace.java index 66098376..6ac6e0ad 100644 --- a/src/main/java/space/space_spring/domain/UserSpace.java +++ b/src/main/java/space/space_spring/entity/UserSpace.java @@ -1,8 +1,9 @@ -package space.space_spring.domain; +package space.space_spring.entity; import jakarta.annotation.Nullable; import jakarta.persistence.*; import lombok.Getter; +import space.space_spring.entity.enumStatus.UserSpaceAuth; @Entity @Getter @@ -34,13 +35,18 @@ public class UserSpace extends BaseEntity { // 스페이스의 관리자 vs 일반 멤버 @Column(name = "user_auth") - private String userAuth; + private String userSpaceAuth; // 스페이스 선택화면에서의 배치 순서 @Column(name = "space_order") private int spaceOrder; - + public void createUserSpace(User user, Space space, UserSpaceAuth userSpaceAuth) { + this.user = user; + this.space = space; + this.userName = user.getUserName(); + this.userSpaceAuth = userSpaceAuth.getAuth(); + } } diff --git a/src/main/java/space/space_spring/entity/enumStatus/UserSpaceAuth.java b/src/main/java/space/space_spring/entity/enumStatus/UserSpaceAuth.java new file mode 100644 index 00000000..7024b35d --- /dev/null +++ b/src/main/java/space/space_spring/entity/enumStatus/UserSpaceAuth.java @@ -0,0 +1,15 @@ +package space.space_spring.entity.enumStatus; + +import lombok.Getter; + +@Getter +public enum UserSpaceAuth { + MANAGER("manager"), + NORMAL("normal"); + + private String auth; + + UserSpaceAuth(String auth) { + this.auth = auth; + } +} diff --git a/src/main/java/space/space_spring/jwt/JwtProvider.java b/src/main/java/space/space_spring/jwt/JwtProvider.java index 429a9752..b7bd58a5 100644 --- a/src/main/java/space/space_spring/jwt/JwtProvider.java +++ b/src/main/java/space/space_spring/jwt/JwtProvider.java @@ -4,7 +4,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import space.space_spring.domain.User; +import space.space_spring.entity.User; import space.space_spring.exception.jwt.unauthorized.JwtInvalidTokenException; import space.space_spring.exception.jwt.unauthorized.JwtMalformedTokenException; import space.space_spring.exception.jwt.bad_request.JwtUnsupportedTokenException; diff --git a/src/main/java/space/space_spring/service/SpaceService.java b/src/main/java/space/space_spring/service/SpaceService.java index fc708420..cbe4798d 100644 --- a/src/main/java/space/space_spring/service/SpaceService.java +++ b/src/main/java/space/space_spring/service/SpaceService.java @@ -2,7 +2,11 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import space.space_spring.dao.SpaceDao; +import space.space_spring.dao.UserDao; +import space.space_spring.entity.Space; +import space.space_spring.entity.User; import space.space_spring.dto.space.PostSpaceCreateRequest; import space.space_spring.dto.space.PostSpaceCreateResponse; @@ -11,17 +15,21 @@ public class SpaceService { private final SpaceDao spaceDao; + private final UserDao userDao; + @Transactional public PostSpaceCreateResponse createSpace(Long userId, PostSpaceCreateRequest postSpaceCreateRequest) { // TODO 1. 스페이스 생성 정보 db insert - Long spaceId = spaceDao.saveSpace(postSpaceCreateRequest); + Space saveSpace = spaceDao.saveSpace(postSpaceCreateRequest); // TODO 2. 유저_스페이스 매핑 정보 db insert - + User manager = userDao.findUserByUserId(userId); + spaceDao.createUserSpace(manager, saveSpace); // TODO 3. jwt에 space 정보 추가 - return new PostSpaceCreateResponse(spaceId); + + return new PostSpaceCreateResponse(saveSpace.getSpaceId()); } } diff --git a/src/main/java/space/space_spring/service/UserService.java b/src/main/java/space/space_spring/service/UserService.java index eb3e79dc..e83a9d17 100644 --- a/src/main/java/space/space_spring/service/UserService.java +++ b/src/main/java/space/space_spring/service/UserService.java @@ -5,7 +5,7 @@ import org.springframework.transaction.annotation.Transactional; import space.space_spring.jwt.JwtProvider; import space.space_spring.dao.UserDao; -import space.space_spring.domain.User; +import space.space_spring.entity.User; import space.space_spring.dto.user.PostUserLoginRequest; import space.space_spring.dto.user.PostUserSignupRequest; import space.space_spring.dto.user.PostUserSignupResponse; @@ -29,12 +29,12 @@ public PostUserSignupResponse signup(PostUserSignupRequest postUserSignupRequest // TODO 2. 회원정보 db insert - Long savedUserId = userDao.saveUser(postUserSignupRequest); + User saveUser = userDao.saveUser(postUserSignupRequest); // TODO 3. JWT 토큰 초기화 (회원가입시에는 토큰 발급 X) String jwt = null; - return new PostUserSignupResponse(savedUserId, jwt); + return new PostUserSignupResponse(saveUser.getUserId(), jwt); } private void validateEmail(String email) { From d093bb6d956fd5ecb345fd4fea2badb77d4f63a1 Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Wed, 17 Jul 2024 02:04:12 +0900 Subject: [PATCH 14/17] =?UTF-8?q?Feat=20=EC=8A=A4=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=20=EC=83=9D=EC=84=B1=20&=20jwt=20=EA=B6=8C=ED=95=9C?= =?UTF-8?q?=20=EC=A0=95=EB=B3=B4=20update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JwtLoginAuth.java} | 4 +- .../JwtLoginAuthHandlerArgumentResolver.java} | 7 +- .../jwtUserSpace/JwtUserSpaceAuth.java | 11 ++ ...tUserSpaceAuthHandlerArgumentResolver.java | 25 +++++ .../space/space_spring/config/WebConfig.java | 25 +++-- .../controller/SpaceController.java | 14 ++- .../controller/TestController.java | 14 ++- .../controller/UserController.java | 4 +- .../java/space/space_spring/dao/SpaceDao.java | 3 +- .../space_spring/dto/jwt/JwtPayloadDto.java | 30 +++++ .../dto/jwt/JwtUserSpaceAuthDto.java | 18 +++ .../dto/space/SpaceCreateDto.java | 12 ++ .../space/space_spring/entity/UserSpace.java | 2 +- .../JwtLoginAuthInterceptor.java} | 18 +-- .../JwtUserSpaceAuthInterceptor.java | 60 ++++++++++ ...JwtProvider.java => JwtLoginProvider.java} | 29 ++--- .../jwt/JwtUserSpaceProvider.java | 106 ++++++++++++++++++ .../space_spring/service/SpaceService.java | 18 ++- .../space_spring/service/UserService.java | 12 +- src/main/resources/application.yml | 5 +- 20 files changed, 361 insertions(+), 56 deletions(-) rename src/main/java/space/space_spring/argument_resolver/{JwtPreAuth.java => jwtLogin/JwtLoginAuth.java} (72%) rename src/main/java/space/space_spring/argument_resolver/{JwtAuthHandlerArgumentResolver.java => jwtLogin/JwtLoginAuthHandlerArgumentResolver.java} (82%) create mode 100644 src/main/java/space/space_spring/argument_resolver/jwtUserSpace/JwtUserSpaceAuth.java create mode 100644 src/main/java/space/space_spring/argument_resolver/jwtUserSpace/JwtUserSpaceAuthHandlerArgumentResolver.java create mode 100644 src/main/java/space/space_spring/dto/jwt/JwtPayloadDto.java create mode 100644 src/main/java/space/space_spring/dto/jwt/JwtUserSpaceAuthDto.java create mode 100644 src/main/java/space/space_spring/dto/space/SpaceCreateDto.java rename src/main/java/space/space_spring/interceptor/{JwtAuthInterceptor.java => jwtLogin/JwtLoginAuthInterceptor.java} (80%) create mode 100644 src/main/java/space/space_spring/interceptor/jwtUserSpace/JwtUserSpaceAuthInterceptor.java rename src/main/java/space/space_spring/jwt/{JwtProvider.java => JwtLoginProvider.java} (77%) create mode 100644 src/main/java/space/space_spring/jwt/JwtUserSpaceProvider.java diff --git a/src/main/java/space/space_spring/argument_resolver/JwtPreAuth.java b/src/main/java/space/space_spring/argument_resolver/jwtLogin/JwtLoginAuth.java similarity index 72% rename from src/main/java/space/space_spring/argument_resolver/JwtPreAuth.java rename to src/main/java/space/space_spring/argument_resolver/jwtLogin/JwtLoginAuth.java index bfd1b19e..cd8d2e4b 100644 --- a/src/main/java/space/space_spring/argument_resolver/JwtPreAuth.java +++ b/src/main/java/space/space_spring/argument_resolver/jwtLogin/JwtLoginAuth.java @@ -1,4 +1,4 @@ -package space.space_spring.argument_resolver; +package space.space_spring.argument_resolver.jwtLogin; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -7,5 +7,5 @@ @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) -public @interface JwtPreAuth { +public @interface JwtLoginAuth { } diff --git a/src/main/java/space/space_spring/argument_resolver/JwtAuthHandlerArgumentResolver.java b/src/main/java/space/space_spring/argument_resolver/jwtLogin/JwtLoginAuthHandlerArgumentResolver.java similarity index 82% rename from src/main/java/space/space_spring/argument_resolver/JwtAuthHandlerArgumentResolver.java rename to src/main/java/space/space_spring/argument_resolver/jwtLogin/JwtLoginAuthHandlerArgumentResolver.java index fb6341cb..aff96769 100644 --- a/src/main/java/space/space_spring/argument_resolver/JwtAuthHandlerArgumentResolver.java +++ b/src/main/java/space/space_spring/argument_resolver/jwtLogin/JwtLoginAuthHandlerArgumentResolver.java @@ -1,4 +1,4 @@ -package space.space_spring.argument_resolver; +package space.space_spring.argument_resolver.jwtLogin; import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.MethodParameter; @@ -9,13 +9,12 @@ import org.springframework.web.method.support.ModelAndViewContainer; @Component -public class JwtAuthHandlerArgumentResolver implements HandlerMethodArgumentResolver { - +public class JwtLoginAuthHandlerArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { // 일단 parameter의 return value type 을 검사하지는 X - return parameter.hasParameterAnnotation(JwtPreAuth.class); + return parameter.hasParameterAnnotation(JwtLoginAuth.class); } @Override diff --git a/src/main/java/space/space_spring/argument_resolver/jwtUserSpace/JwtUserSpaceAuth.java b/src/main/java/space/space_spring/argument_resolver/jwtUserSpace/JwtUserSpaceAuth.java new file mode 100644 index 00000000..074e0a7b --- /dev/null +++ b/src/main/java/space/space_spring/argument_resolver/jwtUserSpace/JwtUserSpaceAuth.java @@ -0,0 +1,11 @@ +package space.space_spring.argument_resolver.jwtUserSpace; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface JwtUserSpaceAuth { +} diff --git a/src/main/java/space/space_spring/argument_resolver/jwtUserSpace/JwtUserSpaceAuthHandlerArgumentResolver.java b/src/main/java/space/space_spring/argument_resolver/jwtUserSpace/JwtUserSpaceAuthHandlerArgumentResolver.java new file mode 100644 index 00000000..2450ecbd --- /dev/null +++ b/src/main/java/space/space_spring/argument_resolver/jwtUserSpace/JwtUserSpaceAuthHandlerArgumentResolver.java @@ -0,0 +1,25 @@ +package space.space_spring.argument_resolver.jwtUserSpace; + +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +@Component +public class JwtUserSpaceAuthHandlerArgumentResolver implements HandlerMethodArgumentResolver { + + @Override + public boolean supportsParameter(MethodParameter parameter) { + // 일단 parameter의 return value type 을 검사하지는 X + return parameter.hasParameterAnnotation(JwtUserSpaceAuth.class); + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { + HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest(); + return request.getAttribute("jwtPayloadDto"); // jwt를 복호화해서 얻은 userId get + } +} diff --git a/src/main/java/space/space_spring/config/WebConfig.java b/src/main/java/space/space_spring/config/WebConfig.java index 03570905..184974bc 100644 --- a/src/main/java/space/space_spring/config/WebConfig.java +++ b/src/main/java/space/space_spring/config/WebConfig.java @@ -5,9 +5,10 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import space.space_spring.argument_resolver.JwtAuthHandlerArgumentResolver; -import space.space_spring.interceptor.JwtAuthInterceptor; -import space.space_spring.jwt.JwtProvider; +import space.space_spring.argument_resolver.jwtLogin.JwtLoginAuthHandlerArgumentResolver; +import space.space_spring.argument_resolver.jwtUserSpace.JwtUserSpaceAuthHandlerArgumentResolver; +import space.space_spring.interceptor.jwtLogin.JwtLoginAuthInterceptor; +import space.space_spring.interceptor.jwtUserSpace.JwtUserSpaceAuthInterceptor; import java.util.List; @@ -15,18 +16,26 @@ @RequiredArgsConstructor public class WebConfig implements WebMvcConfigurer { - private final JwtAuthInterceptor jwtAuthInterceptor; - private final JwtAuthHandlerArgumentResolver authHandlerArgumentResolver; + private final JwtLoginAuthInterceptor jwtLoginAuthInterceptor; + private final JwtUserSpaceAuthInterceptor jwtUserSpaceAuthInterceptor; + + private final JwtLoginAuthHandlerArgumentResolver jwtLoginAuthHandlerArgumentResolver; + private final JwtUserSpaceAuthHandlerArgumentResolver jwtUserSpaceAuthHandlerArgumentResolver; @Override public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(jwtAuthInterceptor) + registry.addInterceptor(jwtLoginAuthInterceptor) .order(1) - .addPathPatterns("/space/**", "/test/**"); // interceptor 적용되야하는 url enum으로 만들어서 여기에 달면 될듯 + .addPathPatterns("/space/**", "/test/**"); + + registry.addInterceptor(jwtUserSpaceAuthInterceptor) + .order(2) + .addPathPatterns("/test111/**"); // interceptor 적용되야하는 url enum으로 만들어서 여기에 달면 될듯 } @Override public void addArgumentResolvers(List argumentResolvers) { - argumentResolvers.add(authHandlerArgumentResolver); + argumentResolvers.add(jwtLoginAuthHandlerArgumentResolver); + argumentResolvers.add(jwtUserSpaceAuthHandlerArgumentResolver); } } diff --git a/src/main/java/space/space_spring/controller/SpaceController.java b/src/main/java/space/space_spring/controller/SpaceController.java index 6d5dac81..b1d1aa16 100644 --- a/src/main/java/space/space_spring/controller/SpaceController.java +++ b/src/main/java/space/space_spring/controller/SpaceController.java @@ -1,5 +1,6 @@ package space.space_spring.controller; +import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; @@ -7,10 +8,13 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import space.space_spring.argument_resolver.JwtPreAuth; +import space.space_spring.argument_resolver.jwtLogin.JwtLoginAuth; +import space.space_spring.argument_resolver.jwtUserSpace.JwtUserSpaceAuth; +import space.space_spring.dto.jwt.JwtPayloadDto; import space.space_spring.dto.space.PostSpaceCreateRequest; import space.space_spring.dto.space.PostSpaceCreateResponse; +import space.space_spring.dto.space.SpaceCreateDto; import space.space_spring.exception.SpaceException; import space.space_spring.response.BaseResponse; import space.space_spring.service.SpaceService; @@ -26,12 +30,16 @@ public class SpaceController { private final SpaceService spaceService; @PostMapping("/create") - public BaseResponse createSpace(@JwtPreAuth Long userId, @Validated @RequestBody PostSpaceCreateRequest postSpaceCreateRequest, BindingResult bindingResult) { + public BaseResponse createSpace(@JwtLoginAuth Long userId, @Validated @RequestBody PostSpaceCreateRequest postSpaceCreateRequest, BindingResult bindingResult, HttpServletResponse response) { if (bindingResult.hasErrors()) { throw new SpaceException(INVALID_SPACE_CREATE, getErrorMessage(bindingResult)); } - return new BaseResponse<>(spaceService.createSpace(userId, postSpaceCreateRequest)); + SpaceCreateDto spaceCreateDto = spaceService.createSpace(userId, postSpaceCreateRequest); + String jwtUserSpace = spaceCreateDto.getJwtUserSpace(); + response.setHeader("Authorization", "Bearer " + jwtUserSpace); + + return new BaseResponse<>(new PostSpaceCreateResponse(spaceCreateDto.getSpaceId())); } } diff --git a/src/main/java/space/space_spring/controller/TestController.java b/src/main/java/space/space_spring/controller/TestController.java index b1ca1bdb..ac6761a7 100644 --- a/src/main/java/space/space_spring/controller/TestController.java +++ b/src/main/java/space/space_spring/controller/TestController.java @@ -3,7 +3,9 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; -import space.space_spring.argument_resolver.JwtPreAuth; +import space.space_spring.argument_resolver.jwtLogin.JwtLoginAuth; +import space.space_spring.argument_resolver.jwtUserSpace.JwtUserSpaceAuth; +import space.space_spring.dto.jwt.JwtPayloadDto; import space.space_spring.response.BaseResponse; @RestController @@ -16,8 +18,14 @@ public String test(){ } @GetMapping("/test/jwt") - public BaseResponse jwtTest(@JwtPreAuth Long userId) { + public BaseResponse jwtLoginTest(@JwtLoginAuth Long userId) { log.info("userId = {}", userId); - return new BaseResponse<>("jwt test 성공"); + return new BaseResponse<>("jwt login test 성공"); + } + + @GetMapping("/test111") + public BaseResponse jwtUserSpaceTest(@JwtUserSpaceAuth JwtPayloadDto jwtPayloadDto) { + log.info("jwtPayloadDto = {}", jwtPayloadDto); + return new BaseResponse<>("jwt user space test 성공"); } } diff --git a/src/main/java/space/space_spring/controller/UserController.java b/src/main/java/space/space_spring/controller/UserController.java index 2f066e48..e7ec94ad 100644 --- a/src/main/java/space/space_spring/controller/UserController.java +++ b/src/main/java/space/space_spring/controller/UserController.java @@ -48,8 +48,8 @@ public BaseResponse login(@Validated @RequestBody PostUse throw new UserException(INVALID_USER_LOGIN, getErrorMessage(bindingResult)); } - String jwt = userService.login(postUserLoginRequest); - response.setHeader("Authorization", "Bearer " + jwt); + String jwtLogin = userService.login(postUserLoginRequest); + response.setHeader("Authorization", "Bearer " + jwtLogin); return new BaseResponse<>(new PostUserLoginResponse("로그인 성공")); } diff --git a/src/main/java/space/space_spring/dao/SpaceDao.java b/src/main/java/space/space_spring/dao/SpaceDao.java index f1fb8be3..e2cf42fd 100644 --- a/src/main/java/space/space_spring/dao/SpaceDao.java +++ b/src/main/java/space/space_spring/dao/SpaceDao.java @@ -24,10 +24,11 @@ public Space saveSpace(PostSpaceCreateRequest postSpaceCreateRequest) { return space; } - public void createUserSpace(User manager, Space saveSpace) { + public UserSpace createUserSpace(User manager, Space saveSpace) { UserSpace userSpace = new UserSpace(); userSpace.createUserSpace(manager, saveSpace, MANAGER); em.persist(userSpace); + return userSpace; } } diff --git a/src/main/java/space/space_spring/dto/jwt/JwtPayloadDto.java b/src/main/java/space/space_spring/dto/jwt/JwtPayloadDto.java new file mode 100644 index 00000000..f697f852 --- /dev/null +++ b/src/main/java/space/space_spring/dto/jwt/JwtPayloadDto.java @@ -0,0 +1,30 @@ +package space.space_spring.dto.jwt; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@NoArgsConstructor +@ToString +public class JwtPayloadDto { + + private Long userId; + + private List userSpaceList = new ArrayList<>(); + + public void saveUserIdToJwt(Long userId) { + this.userId = userId; + } + + public void saveUserSpaceList(List userSpaceList) { + this.userSpaceList = userSpaceList; + } + + public void addJwtUserSpaceAuth(JwtUserSpaceAuthDto jwtUserSpaceAuthDto) { + this.userSpaceList.add(jwtUserSpaceAuthDto); + } +} diff --git a/src/main/java/space/space_spring/dto/jwt/JwtUserSpaceAuthDto.java b/src/main/java/space/space_spring/dto/jwt/JwtUserSpaceAuthDto.java new file mode 100644 index 00000000..ab6c4f56 --- /dev/null +++ b/src/main/java/space/space_spring/dto/jwt/JwtUserSpaceAuthDto.java @@ -0,0 +1,18 @@ +package space.space_spring.dto.jwt; + +import lombok.Getter; +import lombok.ToString; + +import java.util.HashMap; +import java.util.Map; + +@Getter +@ToString +public class JwtUserSpaceAuthDto { + + private Map userSpaceAuthMap = new HashMap<>(); + + public void saveUserSpaceAuth(Long spaceId, String userSpaceAuth) { + userSpaceAuthMap.put(spaceId, userSpaceAuth); + } +} diff --git a/src/main/java/space/space_spring/dto/space/SpaceCreateDto.java b/src/main/java/space/space_spring/dto/space/SpaceCreateDto.java new file mode 100644 index 00000000..c371de16 --- /dev/null +++ b/src/main/java/space/space_spring/dto/space/SpaceCreateDto.java @@ -0,0 +1,12 @@ +package space.space_spring.dto.space; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class SpaceCreateDto { + + private Long spaceId; + private String jwtUserSpace; +} diff --git a/src/main/java/space/space_spring/entity/UserSpace.java b/src/main/java/space/space_spring/entity/UserSpace.java index 6ac6e0ad..35d668b3 100644 --- a/src/main/java/space/space_spring/entity/UserSpace.java +++ b/src/main/java/space/space_spring/entity/UserSpace.java @@ -37,7 +37,7 @@ public class UserSpace extends BaseEntity { @Column(name = "user_auth") private String userSpaceAuth; - // 스페이스 선택화면에서의 배치 순서 + // 스페이스 선택화면에서의 배치 순서 -> 일단 개발 후순위 (계속 0으로 저장) @Column(name = "space_order") private int spaceOrder; diff --git a/src/main/java/space/space_spring/interceptor/JwtAuthInterceptor.java b/src/main/java/space/space_spring/interceptor/jwtLogin/JwtLoginAuthInterceptor.java similarity index 80% rename from src/main/java/space/space_spring/interceptor/JwtAuthInterceptor.java rename to src/main/java/space/space_spring/interceptor/jwtLogin/JwtLoginAuthInterceptor.java index f8728ea3..d196a683 100644 --- a/src/main/java/space/space_spring/interceptor/JwtAuthInterceptor.java +++ b/src/main/java/space/space_spring/interceptor/jwtLogin/JwtLoginAuthInterceptor.java @@ -1,4 +1,4 @@ -package space.space_spring.interceptor; +package space.space_spring.interceptor.jwtLogin; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -6,20 +6,20 @@ import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; -import space.space_spring.jwt.JwtProvider; -import space.space_spring.exception.jwt.unauthorized.JwtExpiredTokenException; import space.space_spring.exception.jwt.bad_request.JwtNoTokenException; import space.space_spring.exception.jwt.bad_request.JwtUnsupportedTokenException; +import space.space_spring.exception.jwt.unauthorized.JwtExpiredTokenException; +import space.space_spring.jwt.JwtLoginProvider; import static space.space_spring.response.status.BaseExceptionResponseStatus.*; @Component @RequiredArgsConstructor -public class JwtAuthInterceptor implements HandlerInterceptor { +public class JwtLoginAuthInterceptor implements HandlerInterceptor{ private static final String JWT_TOKEN_PREFIX = "Bearer "; - private final JwtProvider jwtProvider; + private final JwtLoginProvider jwtLoginProvider; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { @@ -27,14 +27,14 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons validateAccessToken(accessToken); // jwt에서 userId get - Long userId = jwtProvider.getUserIdFromToken(accessToken); - request.setAttribute("userId", userId); + Long userIdFromToken = jwtLoginProvider.getUserIdFromToken(accessToken); + request.setAttribute("userId", userIdFromToken); return true; } private void validateAccessToken(String accessToken) { - if (jwtProvider.isExpiredToken(accessToken)) { + if (jwtLoginProvider.isExpiredToken(accessToken)) { throw new JwtExpiredTokenException(EXPIRED_TOKEN); } @@ -56,4 +56,4 @@ private void validateToken(String token) { } -} +} \ No newline at end of file diff --git a/src/main/java/space/space_spring/interceptor/jwtUserSpace/JwtUserSpaceAuthInterceptor.java b/src/main/java/space/space_spring/interceptor/jwtUserSpace/JwtUserSpaceAuthInterceptor.java new file mode 100644 index 00000000..080d275e --- /dev/null +++ b/src/main/java/space/space_spring/interceptor/jwtUserSpace/JwtUserSpaceAuthInterceptor.java @@ -0,0 +1,60 @@ +package space.space_spring.interceptor.jwtUserSpace; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpHeaders; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; +import space.space_spring.dto.jwt.JwtPayloadDto; +import space.space_spring.jwt.JwtUserSpaceProvider; +import space.space_spring.exception.jwt.unauthorized.JwtExpiredTokenException; +import space.space_spring.exception.jwt.bad_request.JwtNoTokenException; +import space.space_spring.exception.jwt.bad_request.JwtUnsupportedTokenException; + +import static space.space_spring.response.status.BaseExceptionResponseStatus.*; + +@Component +@RequiredArgsConstructor +public class JwtUserSpaceAuthInterceptor implements HandlerInterceptor { + + private static final String JWT_TOKEN_PREFIX = "Bearer "; + + private final JwtUserSpaceProvider jwtUserSpaceProvider; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + String accessToken = resolveAccessToken(request); + validateAccessToken(accessToken); + + // jwt에서 JwtPayloadDto get + JwtPayloadDto jwtPayloadDto = jwtUserSpaceProvider.getJwtPayloadDtoFromToken(accessToken); + request.setAttribute("jwtPayloadDto", jwtPayloadDto); + + return true; + } + + private void validateAccessToken(String accessToken) { + if (jwtUserSpaceProvider.isExpiredToken(accessToken)) { + throw new JwtExpiredTokenException(EXPIRED_TOKEN); + } + + } + + private String resolveAccessToken(HttpServletRequest request) { + String token = request.getHeader(HttpHeaders.AUTHORIZATION); + validateToken(token); + return token.substring(JWT_TOKEN_PREFIX.length()); + } + + private void validateToken(String token) { + if (token == null) { + throw new JwtNoTokenException(TOKEN_NOT_FOUND); + } + if (!token.startsWith(JWT_TOKEN_PREFIX)) { + throw new JwtUnsupportedTokenException(UNSUPPORTED_TOKEN_TYPE); + } + } + + +} diff --git a/src/main/java/space/space_spring/jwt/JwtProvider.java b/src/main/java/space/space_spring/jwt/JwtLoginProvider.java similarity index 77% rename from src/main/java/space/space_spring/jwt/JwtProvider.java rename to src/main/java/space/space_spring/jwt/JwtLoginProvider.java index b7bd58a5..b5aa0ef0 100644 --- a/src/main/java/space/space_spring/jwt/JwtProvider.java +++ b/src/main/java/space/space_spring/jwt/JwtLoginProvider.java @@ -5,42 +5,45 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import space.space_spring.entity.User; +import space.space_spring.exception.jwt.bad_request.JwtUnsupportedTokenException; import space.space_spring.exception.jwt.unauthorized.JwtInvalidTokenException; import space.space_spring.exception.jwt.unauthorized.JwtMalformedTokenException; -import space.space_spring.exception.jwt.bad_request.JwtUnsupportedTokenException; import java.util.Date; import static space.space_spring.response.status.BaseExceptionResponseStatus.*; -@Component @Slf4j -public class JwtProvider { - - @Value("${secret.jwt-secret-key}") - private String JWT_SECRET_KEY; +@Component +public class JwtLoginProvider { + @Value("${secret.jwt-login-secret-key}") + private String JWT_LOGIN_SECRET_KEY; @Value("${secret.jwt-expired-in}") private Long JWT_EXPIRED_IN; + public String generateToken(User user) { - Claims claims = Jwts.claims().setSubject(user.getEmail()); +// Claims claims = Jwts.claims().setSubject(jwtPayloadDto.getUserId().toString()); + Date now = new Date(); Date expiration = new Date(now.getTime() + JWT_EXPIRED_IN); + Long userId = user.getUserId(); + return Jwts.builder() - .setClaims(claims) +// .setClaims(claims) .setIssuedAt(now) .setExpiration(expiration) - .claim("userId", user.getUserId()) - .signWith(SignatureAlgorithm.HS256, JWT_SECRET_KEY) + .claim("userId", userId) + .signWith(SignatureAlgorithm.HS256, JWT_LOGIN_SECRET_KEY) .compact(); } public boolean isExpiredToken(String accessToken) { try { Jws claims = Jwts.parserBuilder() - .setSigningKey(JWT_SECRET_KEY).build() + .setSigningKey(JWT_LOGIN_SECRET_KEY).build() .parseClaimsJws(accessToken); return claims.getBody().getExpiration().before(new Date()); @@ -62,11 +65,11 @@ public boolean isExpiredToken(String accessToken) { public Long getUserIdFromToken(String accessToken) { try { Jws claims = Jwts.parserBuilder() - .setSigningKey(JWT_SECRET_KEY).build() + .setSigningKey(JWT_LOGIN_SECRET_KEY).build() .parseClaimsJws(accessToken); return claims.getBody().get("userId", Long.class); } catch (JwtException e) { - log.error("[JwtTokenProvider.getUserIdFromToken]", e); + log.error("[JwtTokenProvider.getJwtPayloadDtoFromToken]", e); throw e; } } diff --git a/src/main/java/space/space_spring/jwt/JwtUserSpaceProvider.java b/src/main/java/space/space_spring/jwt/JwtUserSpaceProvider.java new file mode 100644 index 00000000..e078c9d0 --- /dev/null +++ b/src/main/java/space/space_spring/jwt/JwtUserSpaceProvider.java @@ -0,0 +1,106 @@ +package space.space_spring.jwt; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.jsonwebtoken.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import space.space_spring.dto.jwt.JwtPayloadDto; +import space.space_spring.dto.jwt.JwtUserSpaceAuthDto; +import space.space_spring.exception.jwt.unauthorized.JwtInvalidTokenException; +import space.space_spring.exception.jwt.unauthorized.JwtMalformedTokenException; +import space.space_spring.exception.jwt.bad_request.JwtUnsupportedTokenException; + +import java.util.Date; +import java.util.List; + +import static space.space_spring.response.status.BaseExceptionResponseStatus.*; + +@Component +@Slf4j +public class JwtUserSpaceProvider { + + @Value("${secret.jwt-user-space-secret-key}") + private String JWT_USER_SPACE_SECRET_KEY; + + @Value("${secret.jwt-expired-in}") + private Long JWT_EXPIRED_IN; + + private final ObjectMapper objectMapper = new ObjectMapper(); + + public String generateToken(JwtPayloadDto jwtPayloadDto) { +// Claims claims = Jwts.claims().setSubject(jwtPayloadDto.getUserId().toString()); + + Date now = new Date(); + Date expiration = new Date(now.getTime() + JWT_EXPIRED_IN); + + Long userId = jwtPayloadDto.getUserId(); + List userSpaceList = jwtPayloadDto.getUserSpaceList(); + String userSpaceListToJson = null; + try { + userSpaceListToJson = objectMapper.writeValueAsString(userSpaceList); + } catch (JsonProcessingException e) { + log.error("Failed to convert userSpaceList to json", e); + } + + return Jwts.builder() +// .setClaims(claims) + .setIssuedAt(now) + .setExpiration(expiration) + .claim("userId", userId) + .claim("userSpaceList", userSpaceListToJson) + .signWith(SignatureAlgorithm.HS256, JWT_USER_SPACE_SECRET_KEY) + .compact(); + + } + + public boolean isExpiredToken(String accessToken) { + try { + Jws claims = Jwts.parserBuilder() + .setSigningKey(JWT_USER_SPACE_SECRET_KEY).build() + .parseClaimsJws(accessToken); + return claims.getBody().getExpiration().before(new Date()); + + } catch (ExpiredJwtException e) { + return true; + + } catch (UnsupportedJwtException e) { + throw new JwtUnsupportedTokenException(UNSUPPORTED_TOKEN_TYPE); + } catch (MalformedJwtException e) { + throw new JwtMalformedTokenException(MALFORMED_TOKEN); + } catch (IllegalArgumentException e) { + throw new JwtInvalidTokenException(INVALID_TOKEN); + } catch (JwtException e) { + log.error("[JwtTokenProvider.validateAccessToken]", e); + throw e; + } + } + + public JwtPayloadDto getJwtPayloadDtoFromToken(String accessToken) { + try { + Jws claims = Jwts.parserBuilder() + .setSigningKey(JWT_USER_SPACE_SECRET_KEY).build() + .parseClaimsJws(accessToken); + + Long userId = claims.getBody().get("userId", Long.class); + String userSpaceListToJson = claims.getBody().get("userSpaceList", String.class); + List userSpaceList = null; + try { + userSpaceList = objectMapper.readValue(userSpaceListToJson, + objectMapper.getTypeFactory().constructCollectionType(List.class, JwtUserSpaceAuthDto.class)); + } catch (JsonProcessingException e) { + log.error("Failed to convert json to userSpaceList", e); + } + + JwtPayloadDto jwtPayloadDto = new JwtPayloadDto(); + jwtPayloadDto.saveUserIdToJwt(userId); + jwtPayloadDto.saveUserSpaceList(userSpaceList); + + return jwtPayloadDto; + } catch (JwtException e) { + log.error("[JwtTokenProvider.getJwtPayloadDtoFromToken]", e); + throw e; + } + } +} diff --git a/src/main/java/space/space_spring/service/SpaceService.java b/src/main/java/space/space_spring/service/SpaceService.java index cbe4798d..00ae53bf 100644 --- a/src/main/java/space/space_spring/service/SpaceService.java +++ b/src/main/java/space/space_spring/service/SpaceService.java @@ -5,10 +5,15 @@ import org.springframework.transaction.annotation.Transactional; import space.space_spring.dao.SpaceDao; import space.space_spring.dao.UserDao; +import space.space_spring.dto.jwt.JwtPayloadDto; +import space.space_spring.dto.jwt.JwtUserSpaceAuthDto; +import space.space_spring.dto.space.SpaceCreateDto; import space.space_spring.entity.Space; import space.space_spring.entity.User; import space.space_spring.dto.space.PostSpaceCreateRequest; import space.space_spring.dto.space.PostSpaceCreateResponse; +import space.space_spring.entity.UserSpace; +import space.space_spring.jwt.JwtUserSpaceProvider; @Service @RequiredArgsConstructor @@ -16,20 +21,27 @@ public class SpaceService { private final SpaceDao spaceDao; private final UserDao userDao; + private final JwtUserSpaceProvider jwtUserSpaceProvider; @Transactional - public PostSpaceCreateResponse createSpace(Long userId, PostSpaceCreateRequest postSpaceCreateRequest) { + public SpaceCreateDto createSpace(Long userId, PostSpaceCreateRequest postSpaceCreateRequest) { // TODO 1. 스페이스 생성 정보 db insert Space saveSpace = spaceDao.saveSpace(postSpaceCreateRequest); // TODO 2. 유저_스페이스 매핑 정보 db insert User manager = userDao.findUserByUserId(userId); - spaceDao.createUserSpace(manager, saveSpace); + UserSpace userSpace = spaceDao.createUserSpace(manager, saveSpace); // TODO 3. jwt에 space 정보 추가 + JwtUserSpaceAuthDto jwtUserSpaceAuthDto = new JwtUserSpaceAuthDto(); + jwtUserSpaceAuthDto.saveUserSpaceAuth(userSpace.getSpace().getSpaceId(), userSpace.getUserSpaceAuth()); + JwtPayloadDto jwtPayloadDto = new JwtPayloadDto(); + jwtPayloadDto.addJwtUserSpaceAuth(jwtUserSpaceAuthDto); - return new PostSpaceCreateResponse(saveSpace.getSpaceId()); + String jwtUserSpace = jwtUserSpaceProvider.generateToken(jwtPayloadDto); + + return new SpaceCreateDto(saveSpace.getSpaceId(), jwtUserSpace); } } diff --git a/src/main/java/space/space_spring/service/UserService.java b/src/main/java/space/space_spring/service/UserService.java index e83a9d17..52256e78 100644 --- a/src/main/java/space/space_spring/service/UserService.java +++ b/src/main/java/space/space_spring/service/UserService.java @@ -3,7 +3,9 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import space.space_spring.jwt.JwtProvider; +import space.space_spring.dto.jwt.JwtPayloadDto; +import space.space_spring.jwt.JwtLoginProvider; +import space.space_spring.jwt.JwtUserSpaceProvider; import space.space_spring.dao.UserDao; import space.space_spring.entity.User; import space.space_spring.dto.user.PostUserLoginRequest; @@ -18,7 +20,7 @@ public class UserService { private final UserDao userDao; - private final JwtProvider jwtProvider; + private final JwtLoginProvider jwtLoginProvider; @Transactional public PostUserSignupResponse signup(PostUserSignupRequest postUserSignupRequest) { @@ -52,12 +54,12 @@ public String login(PostUserLoginRequest postUserLoginRequest) { validatePassword(userByEmail, postUserLoginRequest.getPassword()); // TODO 3. JWT 발급 - String jwt = jwtProvider.generateToken(userByEmail); + String jwtLogin = jwtLoginProvider.generateToken(userByEmail); // TODO 4. JWT db에 insert -> db에 저장해야할까?? - userByEmail.saveJWTtoLoginUser(jwt); + userByEmail.saveJWTtoLoginUser(jwtLogin); - return jwt; + return jwtLogin; } private User findUserByEmail(String email) { diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 4c55f267..c7b96c06 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -11,14 +11,15 @@ spring: jpa: hibernate: - ddl-auto: update # create : 존재하는 table을 전부 drop했다가 다시 생성 -> 테스트용 + ddl-auto: create # create : 존재하는 table을 전부 drop했다가 다시 생성 -> 테스트용 properties: hibernate: format_sql: true show_sql: true secret: - jwt-secret-key: ${JWT_SECRET_KEY} + jwt-login-secret-key: ${JWT_LOGIN_SECRET_KEY} + jwt-user-space-secret-key: ${JWT_USER_SPACE_SECRET_KEY} jwt-expired-in: ${JWT_EXPIRED_IN} logging: From a6b5821c35d74b189093f82477129d316658b25f Mon Sep 17 00:00:00 2001 From: kim_sang_ june <79149384+drbug2000@users.noreply.github.com> Date: Wed, 17 Jul 2024 15:54:10 +0900 Subject: [PATCH 15/17] [chore] set application.yml add build.gradle mysql --- build.gradle | 2 +- src/main/resources/application.yml | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 9041d148..e9ec35e4 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' -// runtimeOnly 'com.mysql:mysql-connector-j' + runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 58c98f82..bb6f85f2 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -20,10 +20,10 @@ spring: on-profile: "devRDB" datasource: - url: ${DATASOURCE_URL_LOCAL} + url: ${DATASOURCE_URL} username: ${DATASOURCE_USERNAME} password: ${DATASOURCE_PASSWORD} - driver-class-name: com.mysql.cj.jdbc.Driver + driver-class-name: jdbc:mysql://com.mysql.cj.jdbc.Driver logging: level: org.hibernate.sql: debug @@ -69,6 +69,8 @@ spring: secret: jwt-secret-key: ${JWT_SECRET_KEY} + jwt-login-secret-key: ${JWT_SECRET_KEY_LOGIN} + jwt-user-secret-key: ${JWT_SECRET_KEY_USER} jwt-expired-in: ${JWT_EXPIRED_IN:3600000} --- From 424b11810235711c2d1b1efcfdf3d7c9d8c3fcc7 Mon Sep 17 00:00:00 2001 From: kim_sang_ june <79149384+drbug2000@users.noreply.github.com> Date: Wed, 17 Jul 2024 16:24:13 +0900 Subject: [PATCH 16/17] [chore] add env setting in gradle.yml --- .github/workflows/gradle.yml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index e38ccf5c..81187f4a 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -88,7 +88,22 @@ jobs: with: distribution: 'temurin' java-version: '17' - # (5) Gradle build (Test 제외) + # (4.5) application.yml file 설정 + - name: Set yml file + uses: microsoft/variable-substitution@v1 + with: + files: ${{ env.RESOURCE_PATH }} + env: + spring.datasource.url: ${{ secrets.RDS_HOST }} + spring.datasource.username: ${{ secrets.RDS_USERNAME }} + spring.datasource.password: ${{ secrets.RDS_PASSWORD }} + secret.jwt-secret-key: ${{secrets.JWT_SECRET_KEY}} + secret.jwt-login-secret-key: ${{secrets.JWT_SECRET_KEY_1}} + secret.jwt-user-secret-key: ${{secrets.JWT_SECRET_KEY_2}} + secret.jwt-expired-in: ${{secrets.JWT_EXPIRED_IN}} + spring.datasource.driver-class-name: com.mysql.cj.jdbc.Driver + + # (5) Gradle build (Test 제외) - name: Build with Gradle uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee with: From 6673efc5267862805235b88f18ce31646795258c Mon Sep 17 00:00:00 2001 From: kim_sang_ june <79149384+drbug2000@users.noreply.github.com> Date: Wed, 17 Jul 2024 16:31:42 +0900 Subject: [PATCH 17/17] [fix] application propertise "jwt-user-space-key" --- src/main/resources/application.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 964ed211..2ce6eb22 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -71,7 +71,7 @@ spring: secret: jwt-secret-key: ${JWT_SECRET_KEY} jwt-login-secret-key: ${JWT_SECRET_KEY_LOGIN} - jwt-user-secret-key: ${JWT_SECRET_KEY_USER} + jwt-user-space-secret-key: ${JWT_SECRET_KEY_USER_SPACE} jwt-expired-in: ${JWT_EXPIRED_IN:3600000} ---